Настроить интерфейс: включить рендеринг, чтобы добавить префикс / постфикс
Мне нужно настроить визуализацию пользовательского интерфейса: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="<START FILE!--#{source}-->"/>
<ui:include src="#{source}">
<ui:insert name="includeParams"/>
</ui:include>
<h:outputText value="<!--END FILE!--#{source}-->"/>
</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 необходимы:
- Определите тег-обертку внутри вашего 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>
- Создайте 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>
- Определите свой TagDecorator в web.xml следующим образом:
<context-param>
<param-name>javax.faces.FACELETS_DECORATORS</param-name>
<param-value>my.package.CommentTagDecorator</param-value>
</context-param>
- Создайте свой 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 -->