Skip to main content

Custom Templates

When HtmlDocSerializer wraps a serialized POJO inside a complete HTML document, the layout of that document is controlled by a page template. By default it uses BasicHtmlDocTemplate (described in BasicHtmlDocTemplate), but you can supply your own to take complete control over the generated markup.

Custom page templates are created by implementing the HtmlDocTemplate interface and associating it with your serializer using the HtmlDocSerializer.Builder.template(Class) setting.

HtmlDocTemplatewriteTo(HtmlDocSerializerSession,HtmlWriter<?>,Object)

The interface defines a single writeTo(session, writer, pojo) method, and the implementation is open-ended — you can write out the page contents any way you wish using the HtmlWriter<?> passed to it. The serialized POJO is available from the session (typically written into the body via session.parentSerialize(writer, pojo)).

BasicHtmlDocTemplate​

The BasicHtmlDocTemplate class defines a default template for HTML documents created by HtmlDocSerializer.

The HTML document created by this template consists of the following structure:

<html>
<head>
<style type='text/css'>
CSS styles and links to stylesheets
</style>
</head>
<body>
<header>
Page header
</header>
<nav>
Navigation links
</nav>
<aside>
Side-bar text
</aside>
<article>
Contents of serialized object
</article>
<footer>
Footer message
</footer>
</body>
</html>

A page drawn by this template, from the petstore's /console/about/beans/BeanDescription endpoint: the header, the navigation links and the serialized bean in the article (this page sets no aside or footer):

A BasicHtmlDocTemplate page: header, navigation links and a serialized BeanDescription

Implementing a template from scratch​

The following template ignores the header/nav/aside/footer settings entirely and renders a bare-bones document consisting of just the serialized POJO wrapped in a <body>:

public class MyTemplate implements HtmlDocTemplate {

@Override
public void writeTo(HtmlDocSerializerSession session, HtmlWriter<?> w, Object o) throws Exception {
w.sTag("html").nl(0);
w.sTag(1, "body").nl(1);
// Serialize the POJO into the body using the parent HtmlSerializer.
session.parentSerialize(w, o);
w.eTag(1, "body").nl(1);
w.eTag("html").nl(0);
}
}

Wire it into a serializer using the builder:

HtmlDocSerializer serializer = HtmlDocSerializer
.create()
.template(MyTemplate.class)
.build();

Extending the basic template​

Implementing HtmlDocTemplate from scratch means reproducing the entire page structure. In most cases it's easier to subclass BasicHtmlDocTemplate and override only the individual section methods you want to change. BasicHtmlDocTemplate breaks the page down into overridable protected methods, each receiving the session, writer, and POJO:

  • head(session, w, o) — the <head> element (delegates to style(...) and script(...)).
  • header(session, w, o) — the <header> element (page title/description/branding).
  • nav(session, w, o) — the <nav> element (navigation links).
  • aside(session, w, o) — the <aside> element (side-bar text).
  • article(session, w, o) — the <article> element (the serialized POJO itself).
  • footer(session, w, o) — the <footer> element (footer message).

There are also companion hasHeader(...), hasNav(...), hasAside(...), hasFooter(...), hasStyle(...), and hasScript(...) predicates that control whether each section is rendered.

The following example overrides just the footer to append a fixed copyright notice while leaving every other section untouched:

public class MyTemplate extends BasicHtmlDocTemplate {

@Override
protected void footer(HtmlDocSerializerSession session, HtmlWriter<?> w, Object o) throws Exception {
// Preserve the default footer behavior...
super.footer(session, w, o);
// ...then add our own content.
w.appendln(3, "<p>Copyright (c) My Company</p>");
}
}

See Also​