Wicket标签中的嵌套链接

问题描述 投票:1回答:4

我想知道在wicket中这样的事情是否可行:

<span wicket:id="label"><a wicket:id="link"></a></span>

链接可以在标签的所需位置上呈现(无需拆分)。

例如,请考虑以下标签:“[LINK]玫瑰[/ LINK]为红色”如果''和'为红色'是动态的,我们必须使用多个标签:

<span wicket:id="firstPartLabel"/><a wicket:id="link"/><span wicket:id="lastPartLabel">

这是非常难看的,我们不能动态插入链接,以便考虑标签qazxsw poi并用适当的链接替换占位符?

谢谢

java wicket
4个回答
3
投票

Wicket消息支持您正在寻找的内容:


0
投票

我解决了这个问题,创建了一个名为LinkLabel的自定义Panel。该组件仍然对标签使用“硬编码标记”,但至少它的工作。

你可以这样使用它:

https://cwiki.apache.org/confluence/display/WICKET/Everything+about+Wicket+internationalization#EverythingaboutWicketinternationalization-Puttingwicketcomponentsintothemessage

该组件的Java代码如下:

LinkLabel myLabel = new LinkLabel("description",
        "First ${link} second", "my link", new ILinkListener() {

            private static final long serialVersionUID = 1L;

            @Override
            public void onLinkClicked() {
                // Your desired onClick action
            }
        });

组件的标记:

public class LinkLabel extends Panel {

    private static final long serialVersionUID = 1L;

    public LinkLabel(String id, String model, String linkName,
            ILinkListener linkListener) {
        super(id);
        setRenderBodyOnly(true);
        String[] split = model.split("\\$\\{link\\}");
        if (split.length == 2) {
            Label first = new Label("first", split[0]);
            Label second = new Label("second", split[1]);

            add(first);
            add(second);
            add(generateLink(linkListener, linkName));
        } else if (split.length == 1) {
            Label first = new Label("first", split[0]);
            Label second = new Label("second");
            second.setVisible(false);
            add(first);
            add(second);
            add(generateLink(linkListener, linkName));
        } else {
            throw new UnsupportedOperationException(
                    "LinkLabel needs the ${link} placeholder!");
        }
    }

    private Link<?> generateLink(final ILinkListener linkListener,
            String linkName) {
        Label linkLabel = new Label("linkLabel", linkName);
        Link<String> link = new Link<String>("link") {
            private static final long serialVersionUID = 1L;

            @Override
            public void onClick() {
                linkListener.onLinkClicked();
            }
        };
        link.add(linkLabel);
        return link;
    }
}

0
投票

如果您想要做的事情就像Twitter的主题标签/用户名链接(处理纯文本并添加特殊段的链接),您可以扩展Label来做到这一点。只需在文本中搜索特殊单词(这里我使用了正则表达式模式,但您可以使用任何其他方法)并将其替换为链接的HTML。

在此示例中,<wicket:panel> <span wicket:id="first"></span> <a wicket:id="link"><span wicket:id="linkLabel"></span></a> <span wicket:id="second"></span> </wicket:panel> 创建了一个指向Ajax行为的链接。它还可以用于创建资源,页面和其他类型组件的链接(一些处理直接链接,一些不处理)。

这个类是一个非常简单的例子,它并不打算支持Twitter的所有语法。

isInternalRef

UPDATED更改了示例以使用Behaviors处理ajax请求。还有其他方法可以做到这一点。例如,您可以使用单一行为来处理所有链接,或使用资源,但这种方式对我来说看起来更干净。


0
投票

一种简单的方法是使用标准的public class TweetLabel extends Label { private static final Pattern USERNAME_HASHTAG_PATTERN = Pattern.compile("\\B([@#*])([a-zA-Z0-9_]+)", Pattern.CASE_INSENSITIVE); private transient CharSequence body; public TweetLabel(String id) { super(id); } public TweetLabel(String id, String label) { super(id, label); } public TweetLabel(String id, Serializable label) { super(id, label); } public TweetLabel(String id, IModel<?> model) { super(id, model); } protected void onLinkClicked(AjaxRequestTarget target, String word) { target.appendJavaScript("alert('You clicked on \"" + JavaScriptUtils.escapeQuotes(word) + "\", and the server knows...');"); } @Override protected void onConfigure() { super.onConfigure(); // process text here, because we can add behaviors here, but not at onComponentTagBody() body = processText(getDefaultModelObjectAsString()); } @Override public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) { replaceComponentTagBody(markupStream, openTag, body); } /** * based on Matcher.replaceAll() */ private CharSequence processText(String text) { Matcher m = USERNAME_HASHTAG_PATTERN.matcher(text); boolean result = m.find(); if (result) { StringBuffer sb = new StringBuffer(); do { final String replacement = getLinkedTextAndAddBehavior(text, m.start(), m.end()); m.appendReplacement(sb, replacement); result = m.find(); } while (result); m.appendTail(sb); return sb; } return text; } private String getLinkedTextAndAddBehavior(String fullText, int start, int end) { final String matchedString = fullText.substring(start, end); final int length = matchedString.length(); final String prefix = matchedString.substring(0, 1); final String identifier = matchedString.substring(1, length); final boolean isUsername = prefix.equals("@"); final boolean isHashtag = prefix.equals("#") && (start == 0 || fullText.charAt(start - 1) != '&'); final boolean isInternalRef = prefix.equals("*"); final String replacement; if (isUsername) { final String url = "https://twitter.com/" + identifier; replacement = "<a href='" + url + "'>" + matchedString + "</a>"; } else if (isHashtag) { final String url = "https://twitter.com/search?src=hash&q=" + UrlEncoder.QUERY_INSTANCE.encode(matchedString, "UTF-8"); replacement = "<a href='" + url + "'>" + matchedString + "</a>"; } else if (isInternalRef) { final LinkedWordBehavior behavior = getOrAddBehavior(new LinkedWordBehavior(identifier)); final String rawFunction = behavior.getCallbackScript().toString(); replacement = String.format("<a href='#' onclick='%s;return false;'>%s</a>", rawFunction, matchedString); } else { replacement = matchedString; } return replacement; } /** * Verify if the behavior was already added, add if not. */ private LinkedWordBehavior getOrAddBehavior(LinkedWordBehavior behavior) { final List<LinkedWordBehavior> behaviors = getBehaviors(LinkedWordBehavior.class); final int index = behaviors.indexOf(behavior); if (index > -1) { return behaviors.get(index); } else { add(behavior); return behavior; } } private final class LinkedWordBehavior extends AbstractDefaultAjaxBehavior { private final String word; public LinkedWordBehavior(String word) { this.word = word; } @Override protected void respond(AjaxRequestTarget target) { final String word = TweetLabel.this.getRequest().getRequestParameters().getParameterValue("word").toString(); if (!Strings.isEmpty(word)) { TweetLabel.this.onLinkClicked(target, word); } } protected void updateAjaxAttributes(AjaxRequestAttributes attributes) { super.updateAjaxAttributes(attributes); attributes.getExtraParameters().put("word", word); } @Override public int hashCode() { return word.hashCode(); } @Override public boolean equals(Object obj) { return word.equals(((LinkedWordBehavior) obj).word); } } } 标签将链接建立为String。然后,您的Java代码可以将<a href=""> </a>作为String提供,其属性为Label。您的html标记是标准的Wicket标签。

在标记中,我建议强调Lorem ipsum文本(在Wicket替换标签后不会出现)。这可以帮助提醒您,在设计标记时,此标签将成为链接。

示例标记:

.setEscapeModelStrings(false)

示例Java:

<span wicket:id="mylabel"><u>Lorem ipsum dolor</u></span>
© www.soinside.com 2019 - 2024. All rights reserved.