Tiles
Tiles is a layout technology which carves pages into different sections or 'tiles'. These can then be controlled and set using an xml file. The easiest way to see this is just from a simple example.Basic Tiles Config
The basic tiles configuration is an xml file (or multiple files) which defines the layouts.
<!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>
<!-- Main layout -->
<definition name="myapp.main" template="/WEB-INF/views/main.jsp">
<put-attribute name="header" value="/WEB-INF/views/header.jsp" />
<put-attribute name="footer" value="/WEB-INF/views/footer.jsp" />
</definition>
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<!-- Main layout -->
<definition name="myapp.main" template="/WEB-INF/views/main.jsp">
<put-attribute name="header" value="/WEB-INF/views/header.jsp" />
<put-attribute name="footer" value="/WEB-INF/views/footer.jsp" />
</definition>
<definition name="myapp.home" extends="myapp.main">
<put-attribute name="body" value="/WEB-INF/views/home.jsp" />
</definition>
JSP Layout
The main.jsp page above is a standard JSP page which has a couple of 'holders' for the tiles elements.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<html>
<head />
<body>
<!-- header -->
<div class="header">
<tiles:insertAttribute name="header" />
</div>
<!-- Central Container -->
<div class="main_content">
<tiles:insertAttribute name="body" />
</div>
<!-- footer -->
<div class="footer">
<tiles:insertAttribute name="footer" />
</div>
</body>
</html>
Controller
The ModelAndView which is returned by the Controller will define the view to use based on the definition name in the tiles configuration. For example
This will use the 'myapp.home' definition which itself extends the 'myapp.main' definition. As a result the full page is rendered using this hierarchy.
ModelAndView mav = new ModelAndView("myapp.home");
This will use the 'myapp.home' definition which itself extends the 'myapp.main' definition. As a result the full page is rendered using this hierarchy.
Spring Config
Finally the spring configuration needs to be told how to resolve the view name. This is standard with spring, whether it is jsp view resolver, Freemarker, etc. For tiles the configuration looks like this,
<!-- Configure Tiles -->
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles/myapp.xml</value>
</list>
</property>
<property name="preparerFactoryClass"
value="org.springframework.web.servlet.view.tiles2.SpringBeanPreparerFactory"/>
value="org.springframework.web.servlet.view.tiles2.SpringBeanPreparerFactory"/>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
</bean>
Here the 'tileConfigurer' gives a list of the definitions that are used. This means that the definitions can be split into logical lumps and you don't end up with a file which is unmanageably large! The 'viewResolver' is a standard spring element which tells spring how to resolve the view name.
Maven
Maven dependencies,
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-extras</artifactId>
<version>3.0.4</version>
</dependency>
Preparer Classes
In the situation of having a menu defined in Tiles you don't want to have to remember to get every controller to put particular elements in the model. An easy way of extracting this is to use a ViewPreparer. Implement the ViewPreparer interface and complete the execute() method. Then in the tiles definition you can add a preparer="myAppPreparer"
<!-- Main layout -->
<definition name="myapp.main" template="/WEB-INF/views/main.jsp" preparer="myAppPreparer">
<put-attribute name="header" value="/WEB-INF/views/header.jsp" />
<put-attribute name="footer" value="/WEB-INF/views/footer.jsp" />
</definition>
The preparer name here is a fully qualified path name by default but can be a spring bean and therefore have its dependencies injected by spring. To make spring resolve these beans you need to have the 'preparerFactoryClass' configured in the spring tilesConfigurer(see above).
The HttpServletRequest can be obtained within a ViewPreparer as follows,
/**
* {@inheritDoc}
*/
@Override
public void execute(final TilesRequestContext tilesRequestContext, final AttributeContext attributeContext)
{
final HttpServletRequest request = (HttpServletRequest) tilesRequestContext.getRequestObjects()[0];
... other code to add to the request ...
}
}
Loose Ends
There are occasions when a url is required within the application or spring context and the url needs to be mapped to the tiles names. This is possible by using a spring mvc:controller
<mvc:view-controller path="my_url" view-name="my.tiles.definition"/>
This then allows the 'my_url' to be used within the application and context.
No comments:
Post a Comment