Apache Tiles is a free open-sourced templating framework for modern Java applications. Based upon the Composite pattern it is built to simplify the development of user interfaces.

Introduction

Building web applications most often than not requires duplicating common page elements across several pages. When adding links to page navigation for instance, one is required to copy/paste these links on all pages that have navigation. This can sometimes prove to be repetitive and wrought with errors.
To avoid code duplication, developers look for tools and/or libraries to make this easier. Shared page elements can be created as autonomous units and reused across the entire web application using these units.
One of such tools that goes a step futher is Apache Tiles. Apache Tiles is a template composition framework. Tiles was originally built to simplify the development of web application user interfaces, but it is no longer restricted to the JavaEE web environment. For complex web sites it remains the easiest and most elegant way to work alongside any MVC technology. Tiles allows authors to define page fragments which can be assembled into a complete page at runtime. These fragments, or tiles, can be used as simple includes in order to reduce the duplication of common page elements or embedded within other tiles to develop a series of reusable templates. These templates streamline the development of a consistent look and feel across an entire application.
The final working sample can be found in the github repository. For advanced usage of tiles refer to this blog post.

Project Structure

At the end of this guide our folder structure will look similar to this:

.
|__src/
|  |__main/
|  |  |__webapp/
|  |  |  |__layouts/
|  |  |  |  |__classic.jsp
|  |  |  |__tiles/
|  |  |  |  |__banner.jsp
|  |  |  |  |__blog_header.jsp
|  |  |  |  |__common_menu.jsp
|  |  |  |  |__credits.jsp
|  |  |  |  |__home_body.jsp
|  |  |  |  |__navigation.jsp
|  |  |  |__WEB-INF/
|  |  |  |  |__tiles.xml
|  |  |  |  |__web.xml
|  |  |  |__index.jsp
|__pom.xml

Prerequisites

Getting Dependencies

In this getting started guide we will use Maven to manage the dependencies. Let’s add the following:

file: pom.xml

<dependencies>
  ...
  <dependency>
    <groupId>org.apache.tiles</groupId>
    <artifactId>tiles-extras</artifactId>
    <version>${tiles-version}</version>
  </dependency>
  ...
</dependencies>

The dependency on tiles-extras pulls in all transitive dependencies of tiles. For this guide, we will be using tiles in a web environment and as such require servlet-api and jsp jars:

<dependencies>
  ...
  <dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>javax.servlet.jsp.jstl-api</artifactId>
    <version>${jsp.jstl.version}</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>${servlet.api.version}</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>${jsp.api.version}</version>
    <scope>provided</scope>
  </dependency>
  ...
</dependencies>

The versions of the various dependencies are represented as placeholders to ease version management:

<properties>
  ...
  <tiles-version>3.0.7</tiles-version>
  <servlet.api.version>3.1.0</servlet.api.version>
  <jsp.api.version>2.3.1</jsp.api.version>
  <jsp.jstl.version>1.2.1</jsp.jstl.version>
</properties>

Setting up Tiles

tiles-definitions are set up in a file called tiles.xml. Add the following snippet:

file: src/main/webapp/WEB-INF/tiles.xml

<tiles-definitions>
  <definition name="myapp.homepage" template="/layouts/classic.jsp">
    <put-attribute name="title" value="Tiles getting started homepage" />
    ...
  </definition>
</tiles-definitions>

The places of interest to note in the above snippet is the name and template attributes of the <definition> element. The name attribute is used to identify the tiles-definition (we would come back to this later) and the template attribute to specify where the template file can be found relative to the servlet context i.e. src/main/webapp.
The child element <put-attribute> of parent element <definition> specifies a name/value pair in our tiles definition. In this instance the page title.
Let us now use the definitions in our jsp template:

file: src/main/webapp/layouts/classic.jsp

<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
  xmlns:tiles="http://tiles.apache.org/tags-tiles"
  xmlns:c="http://java.sun.com/jsp/jstl/core" 
  version="2.0">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <c:url value="/resources/images/favicon.ico" var="faviconurl" />
  <link rel="icon" href="${faviconurl}" />
  <title><tiles:getAsString name="title" /></title>
</head>

<body>
...
</body>

</html>

Notice the <tiles> child element within the <title> element. It is tagged with getAsString which retrieves the title property (Tiles getting started homepage) from the <put-attribute>. To run this we need one more configuration bootstrap in web.xml:

Also take note of the tiles namespace on the second line (xmlns:tiles="http://tiles.apache.org/tags-tiles")

file: src/main/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1">
  <display-name>apache-tiles-gs</display-name>

  <listener>
    <listener-class>org.apache.tiles.extras.complete.CompleteAutoloadTilesListener</listener-class>
  </listener>

  <servlet>
    <servlet-name>Tiles Dispatch Servlet</servlet-name>
    <servlet-class>org.apache.tiles.web.util.TilesDispatchServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Tiles Dispatch Servlet</servlet-name>
    <url-pattern>*.tiles</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

org.apache.tiles.extras.complete.CompleteAutoloadTilesListener is used to load the tiles container.
For this Guide, we have configured Tiles to work directly with the servlet API, without a controller using org.apache.tiles.web.util.TilesDispatchServlet. In the real world, you’ll probably use an MVC framework like Spring or Struts. You have to configure your framework to work with Tiles; please refer to your framework’s documentation for that.

Run this in any compartible servlet 3.1 container to view the output.

Adding Attributes

Now that we have seen how to create definitions, let us add some more attributes to this definition::

file: src/main/webapp/WEB-INF/tiles.xml

<tiles-definitions>
  <definition name="myapp.homepage" template="/layouts/classic.jsp">
    ...
    <put-attribute name="header" value="/tiles/banner.jsp" />
    <put-attribute name="menu" value="/tiles/common_menu.jsp" />
    <put-attribute name="body" value="/tiles/home_body.jsp" />
    <put-attribute name="footer" value="/tiles/credits.jsp" />
    <put-attribute name="heading" value="/tiles/blog_header.jsp" />
    <put-attribute name="navigation" value="/tiles/navigation.jsp" />
  </definition>
</tiles-definitions>

The <put-attribute> elements above all reference file fragments in the src/main/webapp/tiles/ directory. We would create this directory and add the following files to it:

  • banner.jsp
  • blog_header.jsp
  • common_menu.jsp
  • credits.jsp
  • home_body.jsp
  • navigation.jsp

Let us add some content to our JSP files.

file: src/main/webapp/tiles/banner.jsp

<div>
  <nav>
    <a href="#">Home</a> 
    <a href="#">New features</a> 
    <a href="#">Press</a> 
    <a href="#">New hires</a> 
    <a href="#">About</a>
  </nav>
</div>

file: src/main/webapp/tiles/blog_header.jsp

<h1 class="blog-title">Getting started with Tiles</h1>
<p class="lead blog-description">
  The official example template of creating a blog with Bootstrap.
</p>

file: src/main/webapp/tiles/common_menu.jsp

<div>
  <h4>About</h4>
  <p>
    Etiam porta <em>sem malesuada magna</em> mollis euismod. Cras mattis
    consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla
    sed consectetur.
  </p>
</div>
<div>
  <h4>Archives</h4>
  <ol>
    <li><a href="#">March 2014</a></li>
    <li><a href="#">February 2014</a></li>
    <li><a href="#">January 2014</a></li>
    <li><a href="#">December 2013</a></li>
    <li><a href="#">November 2013</a></li>
    <li><a href="#">October 2013</a></li>
    <li><a href="#">September 2013</a></li>
    <li><a href="#">August 2013</a></li>
    <li><a href="#">July 2013</a></li>
    <li><a href="#">June 2013</a></li>
    <li><a href="#">May 2013</a></li>
    <li><a href="#">April 2013</a></li>
  </ol>
</div>
<div>
  <h4>Elsewhere</h4>
  <ol>
    <li><a href="#">GitHub</a></li>
    <li><a href="#">Twitter</a></li>
    <li><a href="#">Facebook</a></li>
  </ol>
</div>

Our example project makes use of Twitter Bootstrap:

file: src/main/webapp/tiles/credits.jsp

<p>
  Blog template built for 
  <a href="//getbootstrap.com">Bootstrap</a> by 
  <a href="//twitter.com/mdo">@mdo</a>.
</p>
<p>
  <a href="#">Back to top</a>
</p>

file: src/main/webapp/tiles/home_body.jsp

<div>
  <h2>Sample blog post</h2>
  <p>
    January 1, 2014 by <a href="#">Mark</a>
  </p>

  <p>
    This blog post shows a few different types of content that's
    supported and styled with Bootstrap. Basic typography, images, and
    code are all supported.
  </p>
  <hr/>
  <p>
    Cum sociis natoque penatibus et magnis 
    <a href="#">dis parturient montes</a>, 
    nascetur ridiculus mus. Aenean eu leo quam. Pellentesque
    ornare sem lacinia quam venenatis vestibulum. Sed posuere consectetur
    est at lobortis. Cras mattis consectetur purus sit amet fermentum.
  </p>
  <blockquote>
    <p>
      Curabitur blandit tempus porttitor. 
      <strong>Nullam quis risus eget urna mollis</strong> 
      ornare vel eu leo. Nullam id dolor id nibh
      ultricies vehicula ut id elit.
    </p>
  </blockquote>
  <p>
    Etiam porta 
    <em>sem malesuada magna</em> mollis euismod. Cras mattis
    consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla
    sed consectetur.
  </p>
</div>

file: src/main/webapp/tiles/navigation.jsp

<nav>
  <ul>
    <li><a href="#">Previous</a></li>
    <li><a href="#">Next</a></li>
  </ul>
</nav>

Putting it all Together

To wrap up, this is the complete tiles-definition:

file: src/main/webapp/WEB-INF/tiles.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
  "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
  "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
  <definition name="myapp.homepage" template="/layouts/classic.jsp">
    <put-attribute name="title" value="Tiles tutorial homepage" />
    <put-attribute name="header" value="/tiles/banner.jsp" />
    <put-attribute name="menu" value="/tiles/common_menu.jsp" />
    <put-attribute name="body" value="/tiles/home_body.jsp" />
    <put-attribute name="footer" value="/tiles/credits.jsp" />
    <put-attribute name="heading" value="/tiles/blog_header.jsp" />
    <put-attribute name="navigation" value="/tiles/navigation.jsp" />
  </definition>
</tiles-definitions>

Now in our welcome page let us make use of our tiles definition name (Remember I said we would come back to it) myapp.homepage:

file: src/main/webapp/index.jsp

<?xml version="1.0" encoding="UTF-8" ?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
  xmlns:tiles="http://tiles.apache.org/tags-tiles"
  xmlns:c="http://java.sun.com/jsp/jstl/core" version="2.0">
  <jsp:directive.page contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" session="false" />
  <jsp:output doctype-root-element="html"
    doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    omit-xml-declaration="true" />

  <tiles:insertDefinition name="myapp.homepage" />

</jsp:root>

Notice the <tiles> element right before the <jsp:root> closing tag, we are calling the tiles-definition by name. This tells tiles to insert the classic.jsp layout in the index page.
Run this in any servlet 3.1 container to see the final output.

When tiles dispatcher servlet is configured, you can serve definition names directly with *.tiles e.g. /myapp.homepage.tiles:

file: src/main/webapp/WEB-INF/web.xml

...
<servlet>
  <servlet-name>Tiles Dispatch Servlet</servlet-name>
  <servlet-class>org.apache.tiles.web.util.TilesDispatchServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>Tiles Dispatch Servlet</servlet-name>
  <url-pattern>*.tiles</url-pattern>
</servlet-mapping>
...

Conclusion

Tiles can be used with web frameworks such as Spring and Struts, and template technologies like JSP and Thymeleaf.
You can find the source to this guide in the github repository. Until the next post, keep doing cool things :+1:.