Reputation: 34271
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
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
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