有many other topics关于如何覆盖JSF中的现有渲染器。所有这些都导致faces-config中的相同条目。您“仅”需要component-family
,renderer-type
,render-kit-id
以及renderer-class
我理解并可以重现所有这些示例,但在我的具体情况下,我想要覆盖<ui:include>
和<ui:insert>
的行为。遗憾的是,我无法找到,我必须在上述属性中添加哪些值,因为文件ui:taglib.xml
并不像其他标记库那样冗长。
你有什么想法,如何覆盖它们?
修改:BalusC提及another topic,它使用<my:include>
或<my:insert>
等自定义标签,但我不想使用这些标签。如果我这样做,我必须重构我现有的所有代码,如果不使用我的自定义taglib,我的未来代码将无法正常工作。
我想在呈现<ui:include>
和<ui:insert>
之前挂钩,这样我就可以重用我即将开发的插件,而不用更改任何现有代码。
答案 0 :(得分:3)
...而不更改任何现有代码
你不能。至少,并非没有紧密耦合到特定的实现(Mojarra或MyFaces)。另一种方法是咬住子弹并将所有<ui:include>
和<ui:define>
替换为<my:include>
和<my:define>
。 Facelets尚未完全抽象/标准化为JSF规范。只有Facelet cache factory,但没有Facelet上下文工厂,否则它很容易。通常,忘记以抽象方式自定义<ui:xxx>
标记。您需要破解实施。
鉴于您正在使用Mojarra 2.1.19,您需要copypaste将其com.sun.faces.facelets.impl.DefaultFaceletContext
类添加到您的Web应用程序项目中,并维护其com.sun.faces.facelets.impl
包。 WAR中的类具有比WAR /WEB-INF/lib
和服务器/lib
中更高的类加载优先级。因此,将使用WAR中的这个。
鉴于您希望与<ui:include>
和<ui:define>
上的Customize ui:include rendering to add prefix/postfix中的问题相同:
示例,假设一个空白的文件.xhtml:
输入
<ui:include src="file.xhtml" />
输出
<!-- START file.xhtml --> <!-- END file.xhtml -->
以下是如何通过编辑copypasted DefaultFaceletContext
类来实现它:
在类中添加一个辅助方法,该方法创建一个注释组件(它只是一个普通的输出文本组件)。
private static UIComponent createComment(String comment) {
UIOutput text = new UIOutput();
text.setValue("\n<!-- " + comment + " -->\n");
return text;
}
在第199行扩展oneliner方法includeFacelet(UIComponent, String)
,如下所示:
parent.getChildren().add(createComment("START INCLUDE " + relativePath));
facelet.include(this, parent, relativePath);
parent.getChildren().add(createComment("END INCLUDE " + relativePath));
使用client.apply(this, parent, name)
扩展第366行的includeDefinition(UIComponent, String)
,如下所示:
int start = parent.getChildCount();
found = client.apply(this, parent, name);
if (found) {
parent.getChildren().add(start, createComment("START DEFINE " + name));
parent.getChildren().add(createComment("END DEFINE " + name));
}
在测试期间,我发现了一个警告。我的HTML <title>
模板如下:
<h:head>
<title><ui:insert name="title">#{view.viewId}</ui:insert></title>
</h:head>
因此,注释也会在<title>
元素内部结束。不幸的是,HTML标题中的注释是invalid语法(仅允许PCDATA
),它们按字面解释,因此显示在文档标题中。您可能希望根据定义的name
或parent
创建黑名单。