2013-07-04 38 views
1

我想知道如果这样的事情有可能在检票口:嵌套链接检票

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

其中链路可以在标签所需的地方被渲染(无需拆分它的) 。

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

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

这是非常丑陋的,我们不能插入链接dinamicaly因此,考虑到标签 The ${link} are red ,代之以适当的链接占位符?

感谢

+1

您是否尝试过创建一个扩展标签并包含链接的新Wicket元素?这就是我想要的。然后在HTML中,您可以创建链接,并在该链接标签的Java文件中创建链接。 – blalasaadri

+0

其实我没有,我认为有人已经做到了,但我会试一试,谢谢。 – Wizche

回答

0

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

你可以用这种方式:

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 
      } 
     }); 

该组件的Java代码如下:

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; 
    } 
} 

标记的组件:

<wicket:panel> 
    <span wicket:id="first"></span> 
    <a wicket:id="link"><span wicket:id="linkLabel"></span></a> 
    <span wicket:id="second"></span> 
</wicket:panel> 
0

如果你想要做的是一样的东西Twitter的包括hashtag /用户名链接(处理纯文本和添加链接到特殊部分),您可以扩展标签来做到这一点。只需在文本中搜索特殊字词(这里我使用了正则表达式模式,但您可以使用任何其他方法),并将其替换为链接的HTML。

在此示例中,isInternalRef创建了一个指向Ajax行为的链接。它也可以用来创建资源,页面和其他类型组件的链接(一些处理直接链接,有些则不)。

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

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); 
     } 
    } 
} 

修订改变处理与行为Ajax请求的例子。还有其他方法可以做到这一点。例如,你可以有一个单一的行为来处理所有的链接,或使用资源,但这种方式看起来更清洁。

+0

谢谢,我还需要对linki操作进行回调,我如何将它添加到您的解决方案中? (即onClick())。 – Wizche