Tiles 3 not Rendering List attributes

Quaternion picture Quaternion · Jan 26, 2013 · Viewed 7k times · Source

I've had no issues with tiles 3.0.1 up until trying to add list attributes to the definitions. There is no error and the definitions render correctly with the exception that the list attributes do not seem to be present on the JSPs.

I'm loading tiles with CompleteAutoloadListener, here is web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <listener>
        <listener-class>org.apache.tiles.extras.complete.CompleteAutoloadTilesListener</listener-class>
    </listener>
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param> 
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener> 
    <welcome-file-list>
        <welcome-file>/index.action</welcome-file>
    </welcome-file-list>
</web-app>

Here is how the definitions look (tiles-defs.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="head-default" template="/WEB-INF/template/head.jsp">
        <put-list-attribute name="items">
            <add-attribute value="/style/cssbase-min.css" />
            <add-attribute value="/style/cssfonts-min.css" />
            <add-attribute value="/style/cssreset-min.css" />
            <add-attribute value="/style/grids-min.css" />
            <add-attribute value="/style/style.css" />
        </put-list-attribute>   
    </definition>

    <definition name="default" template="/WEB-INF/template/template.jsp">
        <put-list-attribute name="items" inherit="true"/>
        <put-attribute name="head" value="head-default"/>
        <put-attribute name="header" value="/WEB-INF/template/header.jsp"/>
        <put-attribute name="body" value="/WEB-INF/template/body.jsp"/>
        <put-attribute name="footer" value="/WEB-INF/template/footer.jsp"/>
    </definition>
    <definition name="REGEXP:\/recruiter#candidate-input\.(.*)"  extends="default">
        <put-attribute name="head" value="/WEB-INF/template/recruiter/head.jsp"/>
        <put-attribute name="body" value="/WEB-INF/content/recruiter/candidate-input.jsp"/>
    </definition>
    <definition name="REGEXP:(.*)#(.*)"  extends="default">
        <put-list-attribute name="items" inherit="true"/>
        <put-attribute name="body" value="/WEB-INF/content{1}/{2}"/>
    </definition>
</tiles-definitions>

Finally here is a tile (head.jsp), where I am trying to output the value of "items", actually I gave up and just wanted to see if iteration would work (there should be 5 items in the list), so just wanted to print five strings but the loops are not entered.

<%@taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <s:iterator value="items">
        iterator,
    </s:iterator>
    <c:forEach var="item" items="${items}">
        ${item}
    </c:forEach>
    <script src="<s:url value='/script/jquery/1.8.1/jquery.min.js'/>"></script>
    <script src="<s:url value='/script/jquery.sort.js'/>"></script>
    <title>A Title</title>
</head>

Any ideas?

Update: Final working header tile, including using struts tags.

<%@taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <tiles:importAttribute name="items"/>
    <s:iterator value="#attr.items">
        <s:property/>
    </s:iterator>
    <script src="<s:url value='/script/jquery/1.8.1/jquery.min.js'/>"></script>
    <script src="<s:url value='/script/jquery.sort.js'/>"></script>
    <title>A Title</title>
</head>

Because tiles places the imported attribute "items" into page scope it can only be access from struts2 using the #attr scope.

Answer

Andrea Ligios picture Andrea Ligios · Jan 26, 2013

In Tiles 2.2 there is an extra row missing in your code an example from Tiles 2.2 documentation :

<tiles:useAttribute id="list" name="items" classname="java.util.List" />

However in tiles 3.0.1 the importAttribute tag is now used:

<tiles:importAttribute name="items"/>

A working solution is then:

<tiles:importAttribute name="items"/>
<c:forEach var="item" items="${items}">
    ${item}
</c:forEach>