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

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

Пример, предположим, что file.xhtml пустое:

Ввод

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

Вывод

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

На данный момент я использую JSF2.2 с MyFaces, есть идеи, как я могу это сделать?


person Fabio    schedule 21.05.2015    source источник
comment
Связанный/дубликат: stackoverflow.com/q/33263233   -  person BalusC    schedule 28.10.2015


Ответы (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:include в коде:

<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>
person skybber    schedule 25.05.2015
comment
Я пробовал это, но кажется, что я не могу использовать его с внутренним ui:param, параметры игнорируются. - person Fabio; 09.06.2015

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

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

person meriton    schedule 21.05.2015

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

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

Необходимы следующие четыре 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 -->
person Jaxt0r    schedule 09.01.2017