2013-07-04 2 views
1

Я интересно, если что-то подобное возможно в калитке:Уплотненная ссылка на этикетке для калитки

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

Если ссылка может быть вынесена на нужном месте этикетки (без необходимости разделения его) ,

Для примера рассмотрим следующую этикетку: "The [LINK] розы [/ LINK] красный" Если 'The' и 'имеют красный' динамичны, мы должны использовать несколько меток:

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

Что является довольно уродливым, мы не можем вставить ссылку dinamicaly, так что, учитывая метку The ${link} are red и замените заполнитель правильной ссылкой?

Благодаря

+1

Вы пробовали создавать новый элемент Wicket, который расширяет Label и содержит ссылку? Вот как я попробую. Затем в HTML у вас будет ссылка, а в файле Java для этого LinkLabel вы можете создать свою ссылку. – 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 (обрабатывать обычный текст и добавить ссылки к специальным сегментам), вы можете расширить Label, чтобы сделать это. Просто найдите текст для специальных слов (здесь я использовал шаблон регулярных выражений, но вы можете использовать любой другой метод) и заменить их на 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

Смежные вопросы