Another way is by using BorderBehavior. See org.apache.wicket.examples.forminput.BeforeAndAfterBorder for an example. The drawback here is that you will need an additional .java + .html pair for each icon type and you'll need to apply it on the Link/Button's label, so you cannot use AbstractLink#setBody(IModel) :-/
On Fri, Oct 19, 2012 at 9:37 AM, Martin Grigorov <[email protected]> wrote: > Hi Jesse, > > I see what you mean and I agree it will work and will be a simple > solution for such requirements. > My only concern is that the API of Behavior becomes bigger and > component rendering will do some more things. Most of the time these > methods will do nothing. > > Have you considered using > org.apache.wicket.markup.transformer.AbstractTransformerBehavior for > this ? > I see how this is more cumbersome too: > - you will need to inject some markup in another markup > - you will need to add two behaviors to the component (I guess you use > ButtonBehavior from wicket-bootstrap already) > > P.S. I've included dev@ so more Wicket devs can give their opinion on this. > > On Thu, Oct 18, 2012 at 11:27 PM, Jesse Long <[email protected]> wrote: >> Hi Wicket Community, >> >> I would like to modify the body of a Component from a Behavior. >> Specifically, I want to add: >> >> <i class="icon icon-calendar"></i> >> >> To the beginning of the of the body of a link, eg: >> >> <a href="#">[here] Some other body</a> >> >> I dont want to extend AbstractLink etc, I want to add this functionality as >> a Behavior. >> >> I cannot see a way to do this without modifying Behavior and Component. Am I >> missing something? Is there a way I can do this without patching the code? >> >> If not, if we must modify the code, how about the patch at the bottom of >> this mail? >> >> 1. Behavior gets two new methods, onBeforeComponentTagBody and >> onAfterComponentTagBody, similar to onComponentTag. >> 2. These new methods take a ComponentTag argument. Is it conceivable >> that the behavior will need to mess around with the ComponentTag, >> especially after renderComponentTag is already called? >> 3. The Behavior does not get the MarkupStream, because I image we dont >> want the Behavior messing around with it? >> 4. I think its pretty safe to implement these calles in >> Component#internalRenderComponent. It is usually called from >> onRender(), and pretty much everything that overrides onRender calls >> it. Right? >> 5. #internalRenderComponent calls onComponentTagBody inside a if >> (tag.isOpen()){} block. Immediately there after, it closes the tag >> in a separate if (tag.isOpen()){} block. This seems to insinuate >> that there is a possibility of onComponentTagBody modifying the >> ComponentTag in some way, possibly leaving is not open. I dont think >> that that should happen, but if it does it could make the calls to >> Bahavior#onAfterComponentTagBody invalid, especially if >> Behavior#onAfterComponentTagBody appends HTML to the response. Thoughts? >> 6. I call Behaviour#onAfterComponentTagBody on the behaviors in reverse >> order, so that we can have multiple behaviors that add content >> before (open tag) and after (close tag) the body. It should be noted >> that Component#notifyBehaviorsComponentRendered() does not do this, >> which may lead to problems if the behaviors add content before and >> after the component. >> >> Thanks, >> Jesse >> >> >> diff --git a/wicket-core/src/main/java/org/apache/wicket/Component.java >> b/wicket-core/src/main/java/org/apache/wicket/Component.java >> index 26bd055..9495dae 100644 >> --- a/wicket-core/src/main/java/org/apache/wicket/Component.java >> +++ b/wicket-core/src/main/java/org/apache/wicket/Component.java >> @@ -22,6 +22,7 @@ import java.util.ArrayList; >> import java.util.Arrays; >> import java.util.Iterator; >> import java.util.List; >> +import java.util.ListIterator; >> import java.util.Locale; >> >> import org.apache.wicket.ajax.IAjaxRegionMarkupIdProvider; >> @@ -2530,9 +2531,27 @@ public abstract class Component >> // Render the body only if open-body-close. Do not render if >> open-close. >> if (tag.isOpen()) >> { >> + for (Behavior b : getBehaviors()) >> + { >> + if (isBehaviorAccepted(b)) >> + { >> + b.onBeforeComponentTagBody(this, tag); >> + } >> + } >> + >> // Render the body. The default strategy will simply call >> the component's >> // onComponentTagBody() implementation. >> getMarkupSourcingStrategy().onComponentTagBody(this, markupStream, tag); >> + >> + ListIterator<? extends Behavior> it = >> getBehaviors().listIterator(); >> + while (it.hasPrevious()) >> + { >> + Behavior b = it.previous(); >> + if (isBehaviorAccepted(b)) >> + { >> + b.onAfterComponentTagBody(this, tag); >> + } >> + } >> } >> >> // Render close tag >> diff --git >> a/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java >> b/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java >> index c916b7d..d9ea133 100644 >> --- a/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java >> +++ b/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java >> @@ -182,6 +182,14 @@ public abstract class Behavior >> public void onComponentTag(Component component, ComponentTag tag) >> { >> } >> + >> + public void onBeforeComponentTagBody(Component component, ComponentTag >> tag) >> + { >> + } >> + >> + public void onAfterComponentTagBody(Component component, ComponentTag >> tag) >> + { >> + } >> >> /** >> * Specifies whether or not this behavior is temporary. Temporary >> behaviors are removed at the >> > > > > -- > Martin Grigorov > jWeekend > Training, Consulting, Development > http://jWeekend.com -- Martin Grigorov jWeekend Training, Consulting, Development http://jWeekend.com
