views:

66

answers:

3

For debug reasons, and on a whim, I'd like to include certain information in a Wicket page's HTML output that is enclosed in HTML comments.

The output would be something like...

<!-- 
<div wicket:id="foo"> 1234 </div>
-->

...where "1234" is some interesting, dynamically created piece of information.

I have tried, to no avail:

  • <!-- <div wicket:id="foo"></div> --> → Wicket complains that element with id "foo" is missing from the HTML page
  • enclose in <wicket:remove> → such sections cannot contain elements with wicket:id
  • label.setVisible(false) → Wicket doesn't output the label at all
  • new Label("foo", "<!-- " + foo + " -->") → the < and > get escaped

So, can you do this with Wicket (easily), or should I just forget about it?

+2  A: 
Label l = new Label("foo", "<!-- " + foo + " -->");
l.setEscapeModelStrings(false);

Its not pretty but it's quick and easy. I also believe there is a specific wicket setting (somewhere in application) which which you can turn on to prevent it from stripping comments, but I honestly can't remember where I saw it.

Edit: Added comment worker

Edit2: Implemented Eelco's behaviour for completeness. Its better than my approach anyway.

public enum Comment {
;
    /**
     * creates a wicket comment (extends label
     */
    public static Label newComment(String id, String comment) {
        Label label = new Label(id, comment);
        label.add(commentBehaviour());
        return label;
    }

    /**
     * Adds &lt;!-- and --&gt around the component.
     */
    public static AbstractBehavior commentBehaviour() {
        return new AbstractBehavior() {
            private static final long serialVersionUID = 1L;

            @Override
            public void beforeRender(Component component) {
                component.getResponse().write("<!--");
            }

            @Override
            public void onRendered(Component component) {
                component.getResponse().write("--!>");
            }
        };
    }
}

add(Comment.newComment("comment","Something worth commenting upon"));
BjornS
Thanks; this works ok for my current need. (And can be made a little bit cleaner with `String.format()`.) I'll accept this after a while, unless something obviously better comes up.
Jonik
@Jonik I think this is *the* way to do it so don't hold your breath :)
jensgram
You inspired me to make this: public enum Comment { ; public static Label newComment(String id, String comment) { Label label = new Label(id, String.format("<-- %s -->", comment)); label.setEscapeModelStrings(false); return label; }} add(Comment.newComment("comment","foo bar goes here"));
BjornS
@Bjorn, your previous comment would be easier to read if edited into the answer. :) But personally I'd prefer this for reusability (similarly as I commented on [Tim's answer](http://stackoverflow.com/questions/3933921/generating-commented-out-content-with-wicket/3934240#3934240)): create custom component (CommentedLabel extends Label) whose constructor takes care of adding the HTML comments and calling setEscapeModelStrings(false).
Jonik
Added to final answer. I guess using the worker class method is matter of preference, in our trunk we already have faaar too many label types, though one I can recommend making would simply be HTMLLabel :) In my own code trunk the example above uses HTMLLabel to avoid having to setEscapeModelStrings(false)
BjornS
Almost off-topic: that (mis)use of `enum` strikes me as odd though. That's just a static utility method, so I'd put it in a (normal) class called Comments, or WicketUtils or so (along with other such methods).
Jonik
You're right that it is not a typical use of enum, however I've had great success with this style of coding, especially in a WicketEnvironment. Enums are implicitly serializable and singleton (if that were required and this example was instancable). It also lends itself very nicely to shorter classes, no need to serializable ID, private constructors etc and Eclipse picks up on them nicely. However you are right, if we had a WicketUtil, it should certainly go there :)
BjornS
+1  A: 

Played around a little and got to this:

Label label = new Label("commented", "Content") {
    @Override
    protected void onComponentTag(ComponentTag tag) {
        tag.setName("!--");
        super.onComponentTag(tag);
    }
};
add(label);

But it's not pretty..: <span wicket:id="commented">This will be replaced</span>
becomes: <!-- wicket:id="commented">Content</!-->

But at least it won't interfere with layout / css styles.

Tim
+1, interesting hack. :) The good thing about this is that you could create a custom component (CommentedLabel extends Label) which overrides onComponentTag(), and after that using this on pages is very clean.
Jonik
... which of course you can do that with Bjorn's solution too, so no big difference there. I guess it's a matter of taste which of these is less "non-pretty". :)
Jonik
Does Wicket convert the closing tag? Or did you mean `<!-- wicket:id="commented">Content</!-->`? (Note the `!` - not that it matters.)
jensgram
Yeah, @jensgram is right: it comes out as `</!-->` (but works nonetheless)
Jonik
@jensgram Yup, you're right.. the close tag had a ! as well.. (Didn't copy-past that part.. =\)
Tim
+1  A: 

How about this?

class CommentOutModifier extends AbstractBehavior {
    private static final long serialVersionUID = 1L;

    @Override
    public void beforeRender(Component component) {
        component.getResponse().write("<!--");
    }

    @Override
    public void onRendered(Component component) {
      component.getResponse().write("-->");
    }
}

add(new Label("tohide", "Hi, can you see me?").add(new CommentOutModifier()));

then, putting:

<span wicket:id="tohide"></span>

in your markup will yield:

<!--<span>Hi, can you see me?</span>-->
Eelco
And the nice thing about that solution is that you can apply it to any component without changing the component itself.
Eelco
Thanks! This looks pretty elegant.
Jonik
If this works as I suspect then its quite an elegant solution, cudos :) I'm revising my answer to implement this method for the sake of completeness but I think Eelco deserves to get the answer for this.
BjornS
It works; tested it to make sure. But don't take my word for it and give it a spin :-)
Eelco
There was actually a bug in onRendered: it used "--!>" instead of "-->". Our front-end developer just noticed this broke the layout badly in IE on a page where I used the commented-out label! I took the liberty to fix the answer. :-)
Jonik