覆盖 ui:insert 和 ui:include-Handler

2023-11-29

many other topics关于如何覆盖 JSF 中的现有渲染器。所有这些都导致 faces-config 中的相同条目。你“只”需要一个component-family, renderer-type, render-kit-id和你的实施renderer-class

我理解并可以重现所有这些示例,但在我的具体情况下,我想重写<ui:include> and <ui:insert>。遗憾的是,我无法找出必须在上述属性中放入哪些值,因为该文件ui:taglib.xml不像其他标签库那么冗长。

您知道如何覆盖它们吗?

Edit:BalusC 提到另一个话题,它使用自定义标签,例如<my:include> or <my:insert>,但我不想使用这些。如果这样做,我必须重构所有现有代码,并且如果不使用自定义标记库,我未来的代码将无法工作。

我想在渲染之前挂钩<ui:include> and <ui:insert>这样我就可以重用我即将开发的插件without更改任何现有代码。


...无需更改任何现有代码

你不能。至少,不是与特定实现(Mojarra 或 MyFaces)紧密耦合。另一种选择是硬着头皮更换所有<ui:include> and <ui:define> by <my:include> and <my:define>。 Facelets 尚未完全抽象/标准化为 JSF 规范。只有一个Facelet 缓存工厂,但没有 Facelet 上下文工厂,否则就很容易了。一般来说,忘记定制<ui:xxx>以抽象的方式标记。你需要破解实施。

鉴于您使用的是 Mojarra 2.1.19,您需要复制粘贴 its com.sun.faces.facelets.impl.DefaultFaceletContext类到您的 Web 应用程序项目中,维护其com.sun.faces.facelets.impl包裹。 WAR 中的类比 WAR 中的类具有更高的类加载优先级/WEB-INF/lib和服务器的/lib。所以你的 WAR 中将使用这个。

鉴于您希望实现与要求相同的目标自定义 ui:include 渲染以添加前缀/后缀 on <ui:include> and <ui:define>:

例如,假设有一个空白 file.xhtml:

Input

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

Output

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

以下是如何通过编辑复制粘贴来实现它DefaultFaceletContext class:

  1. 向创建注释组件的类添加一个辅助方法(这只是一个纯输出文本组件)。

    private static UIComponent createComment(String comment) {
        UIOutput text = new UIOutput();
        text.setValue("\n<!-- " + comment + " -->\n");
        return text;
    }
    
  2. 扩展 oneliner 方法includeFacelet(UIComponent, String)第199行如下:

    parent.getChildren().add(createComment("START INCLUDE " + relativePath));
    facelet.include(this, parent, relativePath);
    parent.getChildren().add(createComment("END INCLUDE " + relativePath));
    
  3. 延长includeDefinition(UIComponent, String)大约第 366 行client.apply(this, parent, name)如下:

    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.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

覆盖 ui:insert 和 ui:include-Handler 的相关文章

随机推荐