Writing Generic Templates

Introduction

Goal

Write a generic template that can be used to render any content type.

Use Case

Sometimes functional requirements dictate that the same generic template can render any  content bean that is passed on to it. As an example, consider a search results page. Typically the controller performs the search query and compiles a list of results. Those results can be of any content type used in the site. You want to render all possible types in a consistent way, say using the title and date of the item. However some content types might not have a date property.

Freemarker Templates

Freemarker provides a missing value test operator ( expression??) which can be used to handle such use cases:

<#list searchResults.items as bean>
  <@hst.link var="link" hippobean=bean.item />
  <ul>
    <li>
      <a href="${link}">${bean.title?html}</a>
      <#if bean.date??>
        <p><@fmt.formatDate value=bean.date.time type="Date"
                           pattern="MMMM d, yyyy h:mm a" /></p>
      </#if>
    </li>
  </ul>
</#list>

Or even safer:

<#if bean.date?? & bean.date.time??>
  <p><@fmt.formatDate value=bean.date.time type="Date"
                     pattern="MMMM d, yyyy h:mm a" /></p>
</#if>

JSP Templates

JSP does not provide the same convenience operator as Freemarker, the HST Tag Library includes a function isReadable which can be used to achieve the same: 

<c:forEach var="bean" items="${requestScope.searchResults.items}" >
  <hst:link var="link" hippobean="${bean.item}"/>
  <ul>
    <li>
      <a href="${link}"><c:out value="${bean.title}"/></a>
      <c:if test="${hst:isReadable(bean, 'date')}">
        <p><fmt:formatDate value="${bean.date.time}"
                           type="Date" pattern="MMMM d, yyyy h:mm a" /></p>
      </c:if>
    </li>
  </ul>
</c:forEach>

The isReadable function also supports nested properties, so the example above can be made even safer:

<c:if test="${hst:isReadable(bean, 'date.time')}">
  <fmt:formatDate value="${bean.date.time}" type="Date"
                  pattern="MMMM d, yyyy h:mm a" />
</c:if>
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?