Jsf 2.2 JSF:自动用CommandLinks替换字符串中的标记

Jsf 2.2 JSF:自动用CommandLinks替换字符串中的标记,jsf-2.2,Jsf 2.2,我有一个类似“你好[大家]!”的字符串。“Everyone”应替换为指向页面对象的commandLink 例如: 我的代码检测到“[everyone]”,并在我的JavaDB数据库中创建一个标题为“everyone”的新“页面”。现在我希望[每个人]都显示为commandLink: Hello <h:commandLink value="everyone" action="#{PageController.getPage(everyone)}" /> 你好 或者别的什么 ATM我

我有一个类似“你好[大家]!”的字符串。“Everyone”应替换为指向页面对象的commandLink

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

Hello <h:commandLink value="everyone" action="#{PageController.getPage(everyone)}" />
你好 或者别的什么

ATM我有此代码来显示带有[]-标记的文本:

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

现在,用特定的commandLink替换标记(即[XYZ])的最佳实践是什么?或者更确切地说:如何用JSF标记替换子字符串(应该呈现它们)?我只找到了创建转换器的可能性,但只找到了转换完整字符串的示例。:/为了找出正确的子字符串,我使用正则表达式

圣诞快乐:)

我的解决方案:

@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;
    }
}
@ApplicationScoped
@命名(“TagViewPhase”)
公共类TagViewPhase实现可序列化{
应用程序;
前期公共无效(阶段事件事件){
如果(app==null){
app=event.getFacesContext().getApplication();
}
if(event.getPhaseId()==PhaseId.RENDER_响应){
scanForPageContent(event.getFacesContext().getViewRoot());
}
}
专用void scanForPageContent(UIComponent组件){
对于(UIComponent i:component.getChildren()){
if(“pageContent.equals(i.getId())){
HtmlOutText内容=(HtmlOutText)i;
HtmlPanelGroup组=generatePageContent(内容);
content.getParent().getChildren().add(组);
content.getParent().getChildren().remove(i);
}否则{
浏览网页内容(i);
}
}
}
私有HtmlPanelGroup generatePageContent(最终HtmlOutText pContent){
List childTree=new ArrayList();
字符串内容=pContent.getValue().toString();
Pattern=Pattern.compile(“\\[(.*?\\\]”);
Matcher Matcher=pattern.Matcher(内容);
整数开始,结束=0;
字符串链接值;
while(matcher.find()){
start=matcher.start();
如果(结束<开始){
HtmlOutText htmlText=(HtmlOutText)app.createComponent(HtmlOutText.COMPONENT_类型);
htmlText.setValue(content.substring(end,start));
添加(htmlText);
}
end=matcher.end();
linkValue=content.substring(开始+1,结束-1);
HtmlCommand链接=(HtmlCommand链接)app.createComponent(HtmlCommand链接.COMPONENT_类型);
link.setValue(linkValue);
setActionExpression(JSFExpression.createMethodExpression(
“#{PageController.switchPageByString(“+linkValue+”)}”,
String.class,
新类[]{}
));
添加(链接);
}
if(end
xhtml文件:

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


您的问题是什么?用特定的commandLinks替换标记(即[XYZ])的最佳实践是什么?或者更确切地说:如何用JSF标记替换子字符串(应该呈现它们)?我只找到了创建转换器的可能性,但只找到了转换完整字符串的示例。:/为了找到正确的子字符串,我使用正则表达式。字符串的起源是什么?是不是有人在表单中键入了一些内容,然后您将其显示出来?是的。它就像一个维基。括号之间的文本代表参考页的标题。有多种用户在InputExtAreas中键入文本。。嗯。。我需要bbcode解析。我的问题是我不知道如何在XHTML文件之外生成commandLinks并用这些commandLinks替换子字符串。即使很难,我也不知道如何将特定对象设置为动作(在XHTML文件之外)。