问题
I need to customize the ui:include renderer in a way that when it generates the HTML output also adds a comment stating the starting and the ending of the included file.
Example, supposing a blank file.xhtml
:
Input
<ui:include src="file.xhtml" />
Output
<!-- START file.xhtml -->
<!-- END file.xhtml -->
At the moment I'm using JSF2.2 with MyFaces, any idea on how I could do that?
回答1:
I would suggest to define following facelet tag :
<?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>
and to use this tag instead ui:include in the code :
<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>
回答2:
ui:include is not a UiComponent
, and doesn't have a renderer. It is a Facelet TagHandler
, and therefore executed when the view is built (or restored). You would have to modify that TagHandler
to include additional ELInstruction
instances with the desired comments into the component tree.
I don't think JSF offers any nice extension point to override a tag handler of an existing tag library. You could define a new tag in a tag library of your own. You could try to replace the existing tag library definition, though I am not sure this is possible for built-in libraries. Or you could shadow the class definition of the original tag handler in the classpath by providing your own definition for that class (which you would obtain by copying and modifying the original source code). All of these approaches require the duplication of framework code, and will therefore be brittle in maintenance.
回答3:
Customization is also possible via the TagDecorator element, but it's some effort to achieve your goal.
But be careful: The solution only works, if there is no <ui:param>
inside the <ui:include>
.
The following four TODOs are necessary:
- Define a wrapper-tag inside your 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>
- Create the xhtml for your wrapper 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>
- Define your TagDecorator in web.xml like this:
<context-param>
<param-name>javax.faces.FACELETS_DECORATORS</param-name>
<param-value>my.package.CommentTagDecorator</param-value>
</context-param>
- Create your TagDecorator and fill it with life. (Taken from this blogpost)
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());
}
}
Finally your output will look like
<!-- START /include/popup.xhtml -->
[...]
<!-- END /include/popup.xhtml -->
来源:https://stackoverflow.com/questions/30368750/customize-uiinclude-rendering-to-add-prefix-postfix