JSF:使用CommandLinks自动替换字符串中的标签

时间:2013-12-25 01:45:11

标签: jsf-2.2

我有一个像“Hello [everyone]!”这样的字符串。应该用指向页面对象的commandLink替换“Everyone”。

例如: 我的代码检测到“[everyone]”并在我的JavaDB数据库中创建一个标题为“everyone”的新“Page”。现在我希望[所有人]将显示为commandLink:

Hello <h:commandLink value="everyone" action="#{PageController.getPage(everyone)}" />

或其他。

ATM我有这个代码用[] -Tags:

显示文本
<h:outputText value="#{PageController.currentPage.latestContent.text}"  />

现在用特定的commandLink替换标签(即[XYZ])的最佳做法是什么?或者更确切地说:我如何用JSF-Tags替换子串(它们应该被渲染)?我只发现了创建转换器的可能性,但只是转换完整字符串的示例。 :/为了找出正确的子字符串,我使用了Regulary Expressions。

圣诞快乐:)

1 个答案:

答案 0 :(得分:0)

我的解决方案:

@ApplicationScoped
@Named("TagViewPhase")
public class TagViewPhase implements Serializable {
    Application app;

    public void beforePhase(PhaseEvent event) {
        if (app == null) {
            app = event.getFacesContext().getApplication();
        }
        if (event.getPhaseId() == PhaseId.RENDER_RESPONSE) {
            scanForPageContent(event.getFacesContext().getViewRoot());
        }
    }

    private void scanForPageContent(UIComponent component) {
        for (UIComponent i : component.getChildren()) {
            if ("pageContent".equals(i.getId())) {
                HtmlOutputText content = (HtmlOutputText) i;
                HtmlPanelGroup group = generatePageContent(content);

                content.getParent().getChildren().add(group);
                content.getParent().getChildren().remove(i);
            } else {
                scanForPageContent(i);
            }
        }
    }

    private HtmlPanelGroup generatePageContent(final HtmlOutputText pContent) {
        List<UIComponent> childTree = new ArrayList<>();

        String content = pContent.getValue().toString();

        Pattern pattern = Pattern.compile("\\[(.*?)\\]");
        Matcher matcher = pattern.matcher(content);

        Integer start, end = 0;
        String linkValue;
        while (matcher.find()) {
            start = matcher.start();

            if (end < start) {
                HtmlOutputText htmlText = (HtmlOutputText) app.createComponent(HtmlOutputText.COMPONENT_TYPE);
                htmlText.setValue(content.substring(end, start));
                childTree.add(htmlText);
            }

            end = matcher.end();
            linkValue = content.substring(start + 1, end - 1);

            HtmlCommandLink link = (HtmlCommandLink) app.createComponent(HtmlCommandLink.COMPONENT_TYPE);
            link.setValue(linkValue);

            link.setActionExpression(JSFExpression.createMethodExpression(
                    "#{PageController.switchPageByString('" + linkValue + "')}",
                    String.class,
                    new Class<?>[]{}
            ));

            childTree.add(link);
        }

        if (end < content.length()) {
            HtmlOutputText htmlText = (HtmlOutputText) app.createComponent(HtmlOutputText.COMPONENT_TYPE);
            htmlText.setValue(content.substring(end, content.length()));

            childTree.add(htmlText);
        }

        HtmlPanelGroup group = (HtmlPanelGroup) app.createComponent(HtmlPanelGroup.COMPONENT_TYPE);
        group.getChildren().addAll(childTree);

        return group;
    }
}

xhtml文件:

<f:view beforePhase="#{TagViewPhase.beforePhase}">
    <h:panelGroup>
        <h:outputText id="pageContent" value="#{PageController.currentPageContent.text}" />
    </h:panelGroup>
</f:view>