views:

378

answers:

3

I am using Struts tiles 1 succesfully, however I have come across a problem when trying to nest tiles.

I currently have a layout like so:

I wish to have another template like this, for use in quite a few user pages:

So I wish to extend the first layout for the user layout. In the tiles definiton I am using:

<definition name=".basic.layout" path="/WEB-INF/jsps/basicLayout.jsp">
    ....

<definition name=".user.layout" extends=".basic.layout">
    <put name="content" value="/WEB-INF/jsps/user/layout.jsp"/>
    ....

<definition name=".user.page" extends=".user.layout">
    <put name="userContent" value="/WEB-INF/jsps/user/page.jsp"/>
    ....

In user/layout.jsp I attempt to show the tile usually, using <tiles:get name="userContent"/>.

And the problem is The requested resource (/WEB-INF/jsps/user/userContent) is not available

A: 

It's been a long while since I've used Struts Tiles, but shouldn't you be using <tiles:insert> instead of <tiles:get>?

That is, something like:

<tiles:insert attribute="userContent" flush="false"/>
ChssPly76
Thanks but no luck, I'm afraid. I am using the same method exactly in the base layout.
Pool
Not sure what you mean by "same method". Have you tried the above? Are you still getting the same error as you've posted? I've looked at one of my old projects that has a very similar setup to what you've described and `<tiles:insert attribute="XXX"/>` is what's being used throughout.
ChssPly76
The error, when changed was different: `ServletException in '/WEB-INF/jsps/user/layout.jsp': Error - Tag Insert : No value found for attribute 'userContent'.` I am using tiles successfully elsewhere but nesting them seem to be the problem. http://www.mail-archive.com/[email protected]/msg24378.html has a similar problem with a solution posted (that I can't get to work).
Pool
A: 

I found some information from here

This solution worked for me.

In this case, usually you have to create a new definition extending from an existing one, fill the attribute in the correct template and assign the new definition as an attribute to the main template.

In other words:

<definition name="product.nav" template="/productNavLayout.jsp">    
    <put-attribute name="productPathNav" value="/productPathNav.jsp" />    
    <put-attribute name="productNav" value="/productNav.jsp" />  
</definition> 

<definition name="product.nav.extended" extends="product.nav">    
    <put-attribute name="productContent" value="product.grid" />  
</definition> 

<definition name="page.products" extends="layout">
    <put-attribute name="content" value="product.nav.extended" />  
</definition>
Pool
A: 

I as can see from your question you use different names for the content attribute. It is content for user.layout and userContent for user.page.

Can you try to use the same name for that attribute either content or userContent?

Hope this helps.

Update. This is quick hack solutions. You can use ignore attribute set to true for tiles:get operation. It will go silently when no userContent defined.

But I think this is something wrong with tiles definitions.

The error massage suggests that you are trying to use tile which is not defined. I compiled an example when .user.layout is an extension of .basic.layout. The difference between two is a body part.

<definition name=".basic.layout" path="/WEB-INF/jsps/basicLayout.jsp">
   <put name="header" value="/WEB-INF/jsps/header.jsp"/>
   <put name="content" value="/WEB-INF/jsps/basicLayout.jsp"/>
   <put name="footer" value="/WEB-INF/jsps/footer.jsp"/>
</definition> 

<!-- extending content part of basic layout -->
<definition name=".user.content" value="/WEB-INF/jsps/user/layout.jsp">
   <put name="userContent" value="/WEB-INF/jsps/user/page.jsp"/>
</definition>

<!-- defining new layout -->
<definition name=".user.layout" extends=".basic.layout">
  <put name="content" value=".user.content"/>
</defnition>

<definition name=".user.page" extends=".user.layout">
  <put name="userContent" value="/WEB-INF/jsps/page.jsp"/>
</definition>

<definition name=".user.info" extends=".user.layout">
  <put name="userContent" value="/WEB-INF/jsps/userInfo.jsp"/>
</definition>

<definition name=".other.page" extends=".basic.layout">
  <put name="content" value="/WEB-INF/jsps/other.jsp"/>
</definition>
Jeka
Hi, thanks for your answer. That was deliberate, the content and userContent coexisted on a page, the userContent being the subpage on the content. The problem was that it definitions didn't cascade (I answered below but I can't mark as resolved until later.)
Pool