You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Jonathan Tougas <jt...@gmail.com> on 2012/06/12 22:18:38 UTC

how to implement a decorator

I'm trying to figure out how to implement a decorator tag. Here's what I
mean:

I want:

<wicket:modBox style="1">
  <span wicket:id="modBoxText"></span>
</wicket:modBox>

to render to:

<div class="mod-style-1">
  <span>FOO!</span>
</div>

with nothing more than the usual "add( new Label( "modBoxText", "FOO!" ) )"
in the panel class. Note that this is different than a border since there
is no add() for the decorator. The goal of this is to create reusable ui
elements that can be inserted into markup without requiring any wiring in
the java class. From what I understand, this _should_ be possible.

I tried to do this with an IComponentResolver by creating an instance of a
border, but I quickly ran into trouble with the component hierarchy when I
did this and tried to add components to the content of the decorator (such
as <span wicket:id="modBoxText"></span>). Here are the artifacts for this
to get an idea:

ModBoxBorderResolver.java
public class ModBoxBorderResolver implements IComponentResolver {
@Override
public Component resolve( MarkupContainer container, MarkupStream
markupStream, ComponentTag tag ) {

if( tag instanceof WicketTag ) {
 String tagName = tag.getName();
 if( tag.getName().equalsIgnoreCase( "modBox" ) ) {
return ModBoxBorder( "modBox" );
}
}
 return null;
}
}

ModBoxBorder.java
public class ModBoxBorder extends Border {
...
}

ModBoxBorder.html
<wicket:border xmlns:wicket="http://wicket.apache.org">
<div wicket:id="div" class="${mod-style}">
<wicket:body />
</div>
</wicket:border>

I also notice BorderBehavior whihc might be another avenue, but I'm not
sure exactly how I could get this to work simply by adding tags to the
markup and an IComponentResolver.

Has anyone done anything like this already? Perhaps there is something
already in Wicket that I'm overlooking.

Re: how to implement a decorator

Posted by Martin Grigorov <mg...@apache.org>.
Hi,

This is possible but I'd recommend to stay away from IComponentResolvers.

You need IMarkupFilter that will register <wicket:modBox> as an auto
component and flag it (either set specific id or userData for the
ComponentTag).
Then your IComponentResolver impl can use that information and resolve
the component at render-time.
See the code of org.apache.wicket.markup.parser.filter.WicketMessageTagHandler.

Additionally check
org.apache.wicket.markup.html.TransparentWebMarkupContainer. You may
need similar functionality to resolve the parent.


For BorderBehavior check
org.apache.wicket.examples.forminput.FormInput.InputForm#InputForm(String).
It uses BeforeAndAfterBorder.
BorderBehavior is a behavior with a markup.
It is quite easy to accomplish what you need by creating a class for
each style, e.g. ModBoxStyleOneBehavior which has
ModBoxStyleOneBehavior.html with such content:

<wicket:border>
 <div class="mod-style-1">
   <wicket:body/>
 </div>
</wicket:border>


On Tue, Jun 12, 2012 at 11:18 PM, Jonathan Tougas <jt...@gmail.com> wrote:
> I'm trying to figure out how to implement a decorator tag. Here's what I
> mean:
>
> I want:
>
> <wicket:modBox style="1">
>  <span wicket:id="modBoxText"></span>
> </wicket:modBox>
>
> to render to:
>
> <div class="mod-style-1">
>  <span>FOO!</span>
> </div>
>
> with nothing more than the usual "add( new Label( "modBoxText", "FOO!" ) )"
> in the panel class. Note that this is different than a border since there
> is no add() for the decorator. The goal of this is to create reusable ui
> elements that can be inserted into markup without requiring any wiring in
> the java class. From what I understand, this _should_ be possible.
>
> I tried to do this with an IComponentResolver by creating an instance of a
> border, but I quickly ran into trouble with the component hierarchy when I
> did this and tried to add components to the content of the decorator (such
> as <span wicket:id="modBoxText"></span>). Here are the artifacts for this
> to get an idea:
>
> ModBoxBorderResolver.java
> public class ModBoxBorderResolver implements IComponentResolver {
> @Override
> public Component resolve( MarkupContainer container, MarkupStream
> markupStream, ComponentTag tag ) {
>
> if( tag instanceof WicketTag ) {
>  String tagName = tag.getName();
>  if( tag.getName().equalsIgnoreCase( "modBox" ) ) {
> return ModBoxBorder( "modBox" );
> }
> }
>  return null;
> }
> }
>
> ModBoxBorder.java
> public class ModBoxBorder extends Border {
> ...
> }
>
> ModBoxBorder.html
> <wicket:border xmlns:wicket="http://wicket.apache.org">
> <div wicket:id="div" class="${mod-style}">
> <wicket:body />
> </div>
> </wicket:border>
>
> I also notice BorderBehavior whihc might be another avenue, but I'm not
> sure exactly how I could get this to work simply by adding tags to the
> markup and an IComponentResolver.
>
> Has anyone done anything like this already? Perhaps there is something
> already in Wicket that I'm overlooking.



-- 
Martin Grigorov
jWeekend
Training, Consulting, Development
http://jWeekend.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org