Настроить интерфейс: включить рендеринг, чтобы добавить префикс / постфикс

Мне нужно настроить визуализацию пользовательского интерфейса:include таким образом, чтобы при генерации HTML-вывода также добавлялся комментарий с указанием начала и конца включаемого файла.

Пример, предполагающий пустое file.xhtml:

вход

<ui:include src="file.xhtml" />

Выход

<!-- START file.xhtml -->
<!-- END file.xhtml -->

В настоящее время я использую JSF2.2 с MyFaces, есть идеи, как мне это сделать?

3 ответа

Решение

Я бы предложил определить следующий тег facelet:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:c="http://java.sun.com/jsp/jstl/core"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:h="http://java.sun.com/jsf/html"
            >
<ui:composition>   
  <h:outputText value="&lt;START FILE!--#{source}--&gt;"/>
  <ui:include src="#{source}">
    <ui:insert name="includeParams"/>
  </ui:include>
  <h:outputText value="&lt;!--END FILE!--#{source}--&gt;"/>
</ui:composition>
</html>

и использовать этот тег вместо UI: включить в код:

<my:include source="file.xhtml">
  <ui:define name="includeParams">
    <ui:param name="param1" value="value1"/>      
    <ui:param name="param2" value="value2"/>      
  </ui:define>
</my:include>

UI: включить не является UiComponentи не имеет рендерера. Это Facelet TagHandlerи, следовательно, выполняется, когда представление построено (или восстановлено). Вы должны изменить это TagHandler включить дополнительные ELInstruction экземпляры с нужными комментариями в дереве компонентов.

Я не думаю, что JSF предлагает какую-либо хорошую точку расширения для переопределения обработчика тегов существующей библиотеки тегов. Вы можете определить новый тег в собственной библиотеке тегов. Вы можете попытаться заменить существующее определение библиотеки тегов, хотя я не уверен, что это возможно для встроенных библиотек. Или вы можете скрыть определение класса исходного обработчика тега в пути к классам, предоставив свое собственное определение для этого класса (которое вы получите, скопировав и изменив исходный исходный код). Все эти подходы требуют дублирования базового кода и поэтому будут хрупкими в обслуживании.

Настройка также возможна с помощью элемента TagDecorator, но это требует определенных усилий для достижения вашей цели.

Но будьте осторожны: решение работает, только если нет <ui:param> внутри <ui:include>,

Следующие четыре TODO необходимы:

  1. Определите тег-обертку внутри вашего taglib.xml

<namespace>http://my-namespace.com/tags/my-tags</namespace>

<tag>
    <tag-name>includeWithComment</tag-name>
    <source>my/package/includeWithComment.xhtml</source>

    <attribute>
        <name>src</name>
    </attribute>
</tag>
  1. Создайте xhtml для вашей оболочки includeWithComment.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition>

    <!-- START ${src} -->
    <ui:include src="${src}" />
    <!-- END ${src} -->

</ui:composition>
</html>
  1. Определите свой TagDecorator в web.xml следующим образом:
<context-param>
    <param-name>javax.faces.FACELETS_DECORATORS</param-name>
    <param-value>my.package.CommentTagDecorator</param-value>
</context-param>
  1. Создайте свой TagDecorator и наполните его жизнью. (Взято из этого поста)
package my.package;

public class CommentTagDecorator implements TagDecorator {

    @Override
    public Tag decorate(Tag tag) {
        if (!tag.getNamespace().equals("http://xmlns.jcp.org/jsf/facelets")
            || !tag.getLocalName().equals("include")
        ) {
            return null;
        }

        return new Tag(tag.getLocation(), "http://my-namespace.com/tags/my-tags",
            "includeWithComment", "t:includeWithComment", tag.getAttributes());
    }
}

Наконец, ваш вывод будет выглядеть

<!-- START /include/popup.xhtml -->
[...]
<!-- END /include/popup.xhtml -->
Другие вопросы по тегам