Hi!

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.

2. In onBeforeRender, quickly switch one of your existing components
to another that you want to render into a string

3. Let your special component render into a string.

4. Restore back to the original component that was supposed to be
rendered onto the web page.

5. It seems to work ok at least if your component is a panel.

Example code:

-------8<----------------------------

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();
  }

-------8<----------------------------

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();
  }


**
Martin

2009/10/30 Martin Makundi <martin.maku...@koodaripalvelut.com>:
> Almost.... still needs some tweaking:
>
> org.apache.wicket.WicketRuntimeException: Unable to find the markup
> for the component. That may be due to transparent containers or
> components implementing IComponentResolver: [MarkupContainer
> [Component id = -]]
>     at 
> org.apache.wicket.MarkupFragmentFinder.find(MarkupFragmentFinder.java:125)
>     at org.apache.wicket.Component.locateMarkupStream(Component.java:3813)
>     at org.apache.wicket.Component.renderComponent(Component.java:2547)
>
> **
> Martin
>
> 2009/10/30 Martin Makundi <martin.maku...@koodaripalvelut.com>:
>> Looking at AjaxRequestTarget, maybe something like this might work?
>>
>>                // substitute our encoding response for the real one so we 
>> can capture
>>                // component's markup in a manner safe for transport inside 
>> CDATA block
>>                final Response originalResponse = response;
>>                StringResponse stringResponse = new StringResponse();
>>                RequestCycle.get().setResponse(stringResponse);
>>
>>                // Initialize temporary variables
>>                final Page page = component.findParent(Page.class);
>>                if (page == null)
>>                {
>>                        // dont throw an exception but just ignore this 
>> component, somehow
>>                        // it got
>>                        // removed from the page.
>>                        // throw new IllegalStateException(
>>                        // "Ajax request attempted on a component that is not 
>> associated
>>                        // with a Page");
>>                        LOG.debug("component: " + component + " with 
>> markupid: " + markupId +
>>                                " not rendered because it was already removed 
>> from page");
>>                        return;
>>                }
>>
>>                page.startComponentRender(component);
>>
>>                try
>>                {
>>                        component.prepareForRender();
>>
>>                        // render any associated headers of the component
>>                        respondHeaderContribution(response, component);
>>                }
>>                catch (RuntimeException e)
>>                {
>>                        try
>>                        {
>>                                component.afterRender();
>>                        }
>>                        catch (RuntimeException e2)
>>                        {
>>                                // ignore this one could be a result off.
>>                        }
>>                        // Restore original response
>>                        RequestCycle.get().setResponse(originalResponse);
>>                        stringResponse.reset();
>>                        throw e;
>>                }
>>
>>                try
>>                {
>>                        component.renderComponent();
>>                }
>>                catch (RuntimeException e)
>>                {
>>                        RequestCycle.get().setResponse(originalResponse);
>>                        stringResponse.reset();
>>                        throw e;
>>                }
>>
>>                page.endComponentRender(component);
>>
>>                // Restore original response
>>                RequestCycle.get().setResponse(originalResponse);
>>
>>                return stringResponse.toString();
>>
>>
>> 2009/10/30 Martin Makundi <martin.maku...@koodaripalvelut.com>:
>>> Hi!
>>>
>>> Can a wicket component be rendered to string in the following use case:
>>>
>>> 1. I have a table (multiple columns and rows). Each row corresponds to
>>> a person. The columns could represent for rexample a calendar for the
>>> person. Monda, tuesday, etc.
>>>
>>> 2. For each row, I have summary information. I have a SummaryPanel
>>> that can show this information at the footer of the table.
>>>
>>> 3. In addition to the footer, I would like to show the SummaryPanel
>>> contents as a tooltip.
>>>
>>> 4. I would like to attach the tooltip onto an icon in each column for
>>> each row (tooltip content different for different rows, same for
>>> different columns on the same row).
>>>
>>> 5. Ideally I would do like this:
>>> populateitem(ListItem item) {
>>>  item.add(new Tooltip("tooltip", new AbstractReadOnlyModel<String>()
>>> { public String getObject() {  RenderUtils.renderToString(new
>>> SummaryPanel("dummy-id"))  } });
>>> }
>>>
>>> I.e., I need to render a panel to a string during an ongoing render.
>>>
>>> I have found an example for rendering a wicket PAGE
>>> * 
>>> http://www.danwalmsley.com/2008/10/21/render-a-wicket-page-to-a-string-for-html-email/
>>>
>>> Note: I need to render just a panel; so I would rather not frame it with a 
>>> page.
>>>
>>> Furthermore, I have found an example about rendering using a new request 
>>> cycle:
>>> * http://www.mail-archive.com/users@wicket.apache.org/msg22167.html
>>>
>>> But in my understanding this cannot be done if an ongoing request is
>>> being processed?
>>>
>>> **
>>> Martin
>>>
>>
>

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

Reply via email to