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