Juha Syrjälä
Juha Syrjälä

Reputation: 34271

Rendering a Wicket component

I have a Wicket panel that is attached to a Page. I need to obtain rendered HTML code that the panel generates. I need the same HTML that the panel generates to output that was sent to the browser. I don't what the HTML from the whole page.

My panel is a read-only so it doesn't matter if the output is re-generated.

private MyPanel myPanel;

public void onIntialize() {
   super.onInitialize();
   add(myPanel = new MyPanel());
}

new AjaxLink() {
  public void onClick(AjaxRequestTarget target) {
    String myPanelHtml = // obtain html somehow from myPanel
    // do stuff with myPanelHtml
  }
}

Are things different if I need rendered HTML from a component that is not a panel? A component that does not provide the markup.

Upvotes: 1

Views: 3393

Answers (2)

spuas
spuas

Reputation: 1693

From Wicket 6.7.0 it can be acomplished easily with

ComponentRenderer.render(Component c)

From wicket page:

Render a page or component to a String

One of the issues that keeps propping up on the user lists is the ability to render a page or component to a String so that you can use Wicket to render HTML email messages. Now you can use ComponentRenderer to actually do so without having to resort to other less obvious methods.

ComponentRenderer exposes two methods: renderComponent and renderPage and they do exactly what their names suggest. Happy emailing!

Although is intended for mailing, you can use it for other purposes as well, of course

Upvotes: 6

Juha Syrjälä
Juha Syrjälä

Reputation: 34271

Based on jordeu's answer and Wicket wiki I made this. It doesn't require modifying component component hierarchy, but in my case the panel is already a part of the page.

However I am bit concerned about changing application settings and using non-public parts of Wicket API.

public static StringResponse getRenderedResponse(final Component container) {
    // store rendered markup to different place
    final Response originalResponse = RequestCycle.get().getResponse();
    StringResponse stringResponse = new StringResponse();
    RequestCycle.get().setResponse(stringResponse);

    // disable "component must be rendered only once per request" -check
    boolean originalComponentCheck = container.getApplication().getDebugSettings().getComponentUseCheck();
    container.getApplication().getDebugSettings().setComponentUseCheck(false);

    try {
        // prepareForRender() is not part of public Wicket API!!
        container.prepareForRender();
        container.render();
        container.afterRender();
    } finally {
        // restore RequestCycle and checks
        container.getApplication().getDebugSettings().setComponentUseCheck(originalComponentCheck);
        RequestCycle.get().setResponse(originalResponse);
    }
    return stringResponse;
}

Usage:

new AjaxLink() {
  public void onClick(AjaxRequestTarget target) {
    StringResponse response = getRenderedResponse(myPanel);
    String myPanelHtml = response.toString();
    // do stuff with myPanelHtml
}

Upvotes: 0

Related Questions