|
Page Edited :
WICKET :
Component rendering
Component rendering has been edited by syl (Nov 25, 2007). Content:Component render steps Since components are rendered as a part of a page, component rendering includes the same steps (see Page rendering):
Component rendering consists of the following actions:
Since all the above actions happen during page render step, IBehavior and IComponentBorder before render and after render methods work differently from Component#onBeforeRender() and onAfterRender() methods. The difference is that for IBehavior and IComponentBorder:
(IBehavior has much more capabilities that just onBeforeRender() and onAfterRender() methods, see IBehavior interface for more details). onRender()Actual rendering process is driven by markup (see page rendering). There is one instance of MarkupStream class per page. It contains tags for all markup on the page and keeps track of the current tag in the markup (see Markup stream). This instance of MarkupStream is passed to onRender() method for every component. Then a component is responsible to advance markup stream to the following tag. There is no restrictions on how many tags a component have to advance markup stream, so component can process as many tags as it wants. Usually component should advance markup stream to the tag next to its closing tag. On the whole Rendering results in component writing something to the instance of Response class (usually this instance wraps HttpServletResponse). It may look like this: getResponse().write("some char sequence"); getResponse().write("<div>a tag</div>");
Note that renderComponent() takes part of the responsibility for advancing markup stream for component tags and if a component use this method it only needs to advance markup for the data between its tags. If a component corresponds to an open-close tag like <span/>, then it does not have to do anything. Method hierarchy for onRender() method
onComponentTag()The onComponentTag() method is designed to read/change tag of a component. The tag is passed as instance of ComponentTag class and then it can be modified. Here are some things that can be done with it: protected void onComponentTag(ComponentTag tag) { super.onComponentTag(tag); final IValueMap values = tag.getAttributes(); // get all attributes final CharSequence href = "" class="code-quote">"href"); // get attribute tag.put("onclick", someJavaScript); // add attribute tag.remove("src"); // remove attribute final String tagName = tag.getName(); // get tag name tag.setName("a"); // change the name of the tag } For more realistic example see Link#onComponentTag() implementation. onComponentTag() is usually the place where a component check if it is used with correct tag using Component#checkComponentTag() and Component#checkComponentTagAttribute(). onComponentTagBody()onComponentTagBody() is designed to read markup from component tag body and to produce output markup. This is also a method where child components should be handled. As parameters this method gets:
WebComponent subclasses (they can not have child components) in onComponentTagBody() implementation usually just write some markup to the Response instance. There is a convenience method for this Component#replaceComponentTagBody(MarkupStream markupStream, ComponentTag tag, CharSequence body) which replaces component's tag body from markup file with the char sequence and advances markup stream. MarkupContainer subclasses can do the same things in onComponentTagBody() as WebComponent but since they can have child components, they are responsible to initiate rendering for children. For this there is a convenience method MarkupContainer#renderComponentTagBody() (see also MarkupContainer#renderAll() method that is used by page here). Basically it calls MarkupContainer#renderNext() method until markup stream reaches closing tag for this parent component. The renderNext() method does exactly the same things as it does in case of rendering a page (! add link), namely it find component corresponding to the current tag and asks this component to render. |
Unsubscribe or edit your notifications preferences
