How to pass values from JSP to tiles attribute?

SD1234 picture SD1234 · Jan 18, 2012 · Viewed 36.4k times · Source

I am converting an existing Tiles 1 webapp to Tiles 2 architecture. I am having trouble passing values from JSP page to tiles attributes.

Here is my tiles definition file (tiles-definition.xml)

<tiles-definitions>

    <definition name="cda.layout" template="/jsp/layouts/layout.jsp">
        <put-attribute name="pageTitle" value="StoryTitle" type="string"/>
        <put-attribute name="pageHeader" value="StoryHeader" type="string"/>
        <put-attribute name="resources" value="" type="string"/>
    </definition>

</tiles-definitions>

The layout.jsp looks like:

<html>
    <head>
    <title><tiles:insertAttribute name="pageTitle" flush="true"/></title> 
    </head>

    <body>
    ...
    ...

    <div class="content">
    <h1><tiles:insertAttribute name="pageHeader" flush="true"/></h1>
    </div>

    ...
    ...
    </body>
</html>

I have a story page which uses the layout and need to pass values to template attributes.

    <%
    // create a business object and populate
    String mytitle= story.getTitle();
    String myheader = story.getHeader();
    %>

<tiles:insertTemplate template="../layouts/layout.jsp"  flush="false" >
    <tiles:putAttribute name="pageTitle" value="${mytitle}"/>
    <tiles:putAttribute name="pageHeader"value="${myheader}"/>
</tiles:insertTemplate>

In the story.jsp, I can System.out.print() the values for mytitle, myheader and they are showing correct. But, these values are NOT passed on to the tile attributes.

Any idea how to fix this?

Answer

JB Nizet picture JB Nizet · Jan 18, 2012

${mytitle} is a JSP EL expression which means: find an attribute in page scope, or request scope, or session scope, or application scope, named "mytitle".

By defining a scriptlet variable, you haven't defined an attribute in any of these scopes. It would work if you had

pageContext.setAttribute("mytitle", mytitle);

But using scriptlets in JSPs is bad practice. I don't know where your story bean comes from, but it's probably a request attribute. If so, you can define a new page-scope attribute this way, using the JSTL:

<c:set var="mytitle" value="${story.title}"/>

This is unnecessary though, since you could use this expression directly in the tiles tag:

<tiles:putAttribute name="pageTitle" value="${story.title}"/>

Read more about the JSP EL in this tutorial.