Wrapping Component Contents
An HST Component can set a wrapper element for its rendered content to make it easy to refer the content markup elements from client-side technologies such as JavaScript.
An HST Component can simply invoke HstResponse#setWrapperElement(Element) to set its wrapper element or its rendering template JSP or Freemarker template page could contain <hst:wrapperElement /> tag to do the same thing as HstResponse#setWrapperElement(Element)invocation.
What do you do when you need to handle some markup contents of HST Component(s) from the client-side?
Suppose your component renders the following:
<h1>Always Look on the Bright Side of Life (from Monty Python)</h1>
<p>Some things in life are bad. They can really make you mad. Other things just make you swear and curse. When you're chewing on life's gristle. Don't grumble, give a whistle. And this'll help things turn out for the best...<p>
If you want to refer the rendered markup contents above, you can wrap the contents in your template (JSP or freemarker) page as follows:
<span id="component1" class="wrapper">
<h1>Always Look on the Bright Side of Life (from Monty Python)</h1>
<p>Some things in life are bad. They can really make you mad. Other things just make you swear and curse. When you're chewing on life's gristle. Don't grumble, give a whistle. And this'll help things turn out for the best...<p>
</span>
So, now you can use DOM accesses or CSS Selector to refer the contents because all rendered markups are now wrapped by a span with id and css attributes.
Obviously, you do not want to add the wrapper elements manually in every JSP/freemarker template. You can do this as follows:
HstResponse interface provides the following methods:
import org.w3c.dom.Element; public void setWrapperElement(Element element); public Element getWrapperElement();
If you want to wrap the rendered markups of a component, you can simply set a wrapper element for the component by using HstResponse#setWrapperElement(Element);
For example, if you want to wrap every component markup content, then you could add the following codes into the #doBeforeRender() method of the base component class:
// BaseComponent.java public void doBeforeRender(HstRequest request, HstResponse) throws HstComponentException { // ... // Sets wrapper element for each component Element wrapperElem = response.createElement("span"); wrapperElem.setAttribute("class", "wrapper"); response.setWrapperElement(wrapperElem); // ... }
If your component extends the base component class above with super.doBeforeRender(...), then your component will be rendered with a wrapper element you specified in the base component even though you don't modify each template page manually.
One more minor tip is that you can set a wrapper element in the template page by using a tag library if you want:
< hst:element var="wrapperElem" name="span">
< hst:attribute name="id" value="component1" />
< hst:attribute name="class" value="wrapper" />
</ hst:element>
< hst:setWrapperElement element="${wrapperElem}" />
In Freemarker template, you can use the tag like the following:
<@ hst.element var="wrapperElem" name="span">
<@ hst.attribute name="id" value="component1" />
<@ hst.attribute name="class" value="wrapper" />
</@ hst.element>
<@ hst.setWrapperElement elementByBeanPath="wrapperElem" />
The tag library usage above is just invoking HstResponse#setWrapperElement(Element) operation. So, you can choose either approach. Because the render page template is invoked after doBeforeRender() of a component, this tag library usage could be regarded as overriding the wrapper element by re-invoking HstResponse#setWrapperElement(Element) method.