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 <j...@unknown.za.net> 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

Reply via email to