Here is a way to render panel markup to string.

It is a bit of a tweak, I admit, but what can you do.

  1. Assume you have components on your page, ready to be rendered.
  1. In onBeforeRender, quickly switch one of your existing components to another that you want to render into a string
  1. Let your special component render into a string.
  1. Restore back to the original component that was supposed to be rendered onto the web page.
  1. It seems to work ok at least if your component is a panel.

Example code:

somewhere in your page hierarchy that is actually rendered

  /**
   * @see org.apache.wicket.Page#onBeforeRender()
   */
  @Override
  protected void onBeforeRender() {
    System.out.println("\n-----------------------------------------\n" 
        + MarkupUtils.renderToString(loginForm, new IntroductionPanel(loginForm.getId())));
    super.onBeforeRender();
  }


MarkupUtils.public static String renderToString(final Component parentDonorComponent, final Component component) {
    if (!component.getId().equals(parentDonorComponent.getId())) {
      throw new IllegalStateException("Component will try to substitute parentDonorComponent to render. Donor and string render Component id's must be equal.");
    }
    
    final Response originalResponse = RequestCycle.get().getResponse();
    StringResponse stringResponse = new StringResponse();
    RequestCycle.get().setResponse(stringResponse);
    MarkupContainer parentComponent = parentDonorComponent.getParent(); 
    parentComponent.remove(parentDonorComponent);

    try {
      parentComponent.add(component);
      
      try {
        component.prepareForRender();
        component.renderComponent();
      } catch (RuntimeException e) {
        component.afterRender();
        throw e;
      }
    } finally {
      // Restore original component
      parentComponent.replace(parentDonorComponent);
      // Restore original response
      RequestCycle.get().setResponse(originalResponse);
    }

    return stringResponse.toString();
  }

  • No labels