Hst Component Configuration

HST Components are made up of a composite structure of components, which can best be seen as a HMVC pattern. The hierarchy of components typically resembles the webpage to load. HstComponents must have at least a java class (controller) and a renderer (view). If there is no componentclassname configured, the HST uses a built-in default class. 

The rendered output of a Hst Component is flushed into the renderer of the parent Component. This is done through the hst:include tag. The root Component writes to the HTTP response. For example if globally a, say news page, on the website has the following structure:

 

Then the component hierarchy would be:

/news:
  /header:
  /body:
    /left:
    /middle:
    /right:
  /footer:

Examples of possible JSP templates:

layout.jsp

<html>
  <head>
  </head>
  <body>
    <hst:include ref="header"/>
    <hst:include ref="body"/>
    <hst:include ref="footer"/>
  </body>
</html>

body.jsp

<div id="body">
  <div id="left">
    <hst:include ref="left"/>
  </div>
  <div class="middle">
    <hst:include ref="content"/>
  </div>
  <div id ="right">
    <hst:include ref="right"/>
  </div>
</div>

 

Or in case of Freemarker templates:

layout.ftl

<html>
  <head>
  </head>
  <body>
    <@hst.include ref="header"/>
    <@hst.include ref="body"/>
    <@hst.include ref="footer"/>
  </body>
</html>

body.ftl

<div id="body">
  <div id="left">
    <@hst.include ref="left"/>
  </div>
  <div class="middle">
    <@hst.include ref="content"/>
  </div>
  <div id ="right">
    <@hst.include ref="right"/>
  </div>
</div>

Left, middle, right, footer and header will also have some renderer associated with it. The output from for example  left will be flushed to the  body.jsp at the location of  <hst:include ref=”left”/>. Note that as renderers, for a single page, freemarker and jsps can be used intertwined: For example, the output of the left component can be rendered by a freemarker script and flushed to some include in body.jsp.

Component Repository Configuration

In the repository, the component configuration is stored below hst:abstractpageshst:pages and  hst:components. Technically there is no difference between hst:pages and hst:components: The distinction is there merely for readability. In general, a SiteMapItem has a hst:componentconfigurationid that points to a root component below hst:pages. The  hst:componentconfigurationid should never point to a component below hst:abstractpages however.

As webpages in general have many common parts, the Component configuration supports an advanced extension mechanism to support fine grained inheritance. For example, the header, left(menu) and footer component can very well be the same for every page of the site. These could thus be part of the 'standard' component. Extending a Component is done through the property  hst:referencecomponent. All descendant components of the referenced component and the referenced component are merged into the component that references it. Suppose that component X references component Y. Merging is then done as follows:

  1. All properties that are explicitly defined on X override the same properties on Y. For the multivalued properties hst:parameternames and hst:parametervalues, the parameter names & values which are on Y but not on X are merged into the parameters from X.

  2. All child nodes including all descendants from Y that are not already part of X are appended to X

  3. All child nodes from Y that are also on X are merged. Merging is done through repeating step 1 and 2

  4. Multiple referencing is supported: Thus Y can in turn reference Z. When X references Y in this case, first Z is merged into Y before Y is merged into X.

Every component also can have an  hst:template associated with it (which is allowed to be inherited from another component) that contains a reference to the renderer for this component: Typically the renderer is some jsp or freemarker script, where the latter can be on file system, embedded on the classpath or stored in the repository. For example the Component has a property:  hst:template = overview.main.content.

This assumes there is a template below /hst:hst/hst:configurations/{myproject}/hst:templates with node name  overview.main.content. This template either contains the property hst:renderpath containing the location of the render script (classpath or in Web Files), or it has a property hst:script containing the freemarker script to run. In the case of a hst:script property in a hst:template, the hst:template node name must end with .ftl. Thus for example news.main.content.ftl.

Putting it all together in some pictures: suppose, we have matched a news sitemap item.

Assume the news sitemap item with the following properties:

The property  hst:relativecontentpath is the path relative to  /hst:hst/hst:sites/myproject/hst:content. The first property,  hst:componentconfigurationid, has a value of  hst:pages/newsoverview, which is the root component id for the news overview page. Expand the  hst:pages node and click on the  newsoverview node. Its properties look like this:

The  hst:referencecomponent property means that this page extends another component configuration, namely  hst:pages/overview. That other page in turn extends yet another component configuration, namely the one below  hst:abstractpages/base. All this can be seen in the following image:

The  overview page has a child node called  main and inside this there is another node named  content. It points to the  standard page, which also has some children. All these children will invoke some rendering. This means that the following nodes will be all taken into account to render the html page:  headermainleftmenuright and  content

The configuration for for example  overview/main/content is as follows:

The property  hst:referencecomponent points to the node  hst:components/overview, which has the following properties:

The overview component has a property  hst:componentclassname containing the Java class name of the component. This class contains the business logic: it fetches the data and prepares it for rendering. The property  hst:template refers to the name of the template that renders the component, relative to the node  hst:templates. The template node  overview.main.content has the following properties:

In the last image you can see the property  hst:renderpath that contains the path to the JSP used to render the overview page:  jsp/overview/main/content.jsp. This JSP renders the centre column of the news overview page. The header, left and right columns are rendered in a similar way, and you can easily find the JSP that does the actual work by following the reference tree like we just did for the news overview page. Instead of a JSP you can also use a freemarker template. All JSP files reside in

myproject/site/webapp/src/main/webapp/WEB-INF/jsp

As a best practice, the name of a template nodes should reflect its location in the page hierarchy. The JSPs should be structured in a similar way. For example, the component in the page node ' hst:pages/overview/main/content' should be rendered by the template ' hst:templates/overview.main.content' that refers to the JSP file ' WEB-INF/jsp/overview/main/content.jsp'. This naming scheme allows you to quickly locate the JSP of each node in the page hierarchy.

Troubleshooting: Warning being logged starting with 'POSSIBLE WASTE DETECTED'

During page rendering, you might see in the logs a message something like the one below:

POSSIBLE WASTE DETECTED in request 'Request{ method='GET', scheme='http', host='localhost:8080', requestURI='/site/', queryString='null'}' : Component '/hst:hst/hst:configurations/gettingstarted/hst:workspace/hst:containers/homepage/main' gets rendered but never adds anything to the response. Its renderer 'classpath:vbox.ftl' is never flushed to a parent component. This might be waste you are not aware of. If it is on purpose, for example because the component does only some processing that does not involve direct response contribution, you can mark the component with 'hst:suppresswastemessage = true'.

This means that some HstComponent gets its #doBeforeRender method invoked and its backing JSP or Freemarker template gets invoked. However, the result gets never included in a parent response and does thus add nothing to the final HTTP response. If it is on purpose, for example because the HstComponent only does some processing (like checking some state and for example if not ok, short-circuit page rendering by throwing an exception), you can suprress the warning by adding 

hst:suppresswastemessage: true

to the backing Hst component configuration node. Note however that in general, the warning message does imply pure waste and should be fixed by investigating whether the component should be flushed to the parent by an <hst:include> tag in the parent renderer or whether the component configuration should just be removed or whether the inheritance of the component tree should be changed.

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?