You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tiles.apache.org by Zach Bailey <zn...@wethecitizens.com> on 2008/12/08 19:21:05 UTC

Tiles 2.1 Attribute Duplication/Overwriting, Possible Bug?

Hi all,

I was trying some of the new Tiles 2.1 features today, specifically  
cascading attributes. I like this new feature a lot and it seems to  
finally solve some of the challenges I have faced with tiles in the  
past.

I am using the newest tiles release (2.1.0 beta) in conjunction with  
Spring Web MVC.

However, I have run into what seems to be a rather strange problem.  
First, let me show you my definitions:

<definition name="wrapper" template="/layouts/wrapper.jsp">
     <put-attribute name="content" value="/common/blank.jsp"/>
</definition>

<definition name="leftColumnMain" extends="wrapper">
     <put-attribute name="content" value="/layouts/leftColumnMain.jsp"/>
     <put-attribute name="main" value="/common/blank.jsp"  
cascade="true"/>
     <put-attribute name="sidebar" value="/common/blank.jsp"  
cascade="true"/>
</definition>

<definition name="leftColumnTest" template="/pages/leftColumnTest.jsp"/>

Essentially, I am constructing a "base" layout - the wrapper - which  
contains just the most common items (wrapper.jsp) :

<%-- taglibs removed for brevity --%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd 
">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
   <head>
     <title>Left Column Main</title>
   </head>
   <body>
     <tiles:insertAttribute name="content"/>
   </body>
</html>

which is then extended by a more specific layout which defines a 67%  
left column and 33% right column (leftColumnMain.jsp) :

<%-- taglibs removed for brevity --%>
     <!-- Left column. -->
     <div class="prepend-2 span-31 last">
       <tiles:insertAttribute name="main"/>
     </div>
     <!-- Closes left column. -->

     <!-- Right column. -->
     <div class="prepend-1 span-14 append-1 last">
       <tiles:insertAttribute name="sidebar"/>
     </div>
     <!-- Closes right column. -->

which is then used for a "leaf node" page just to test all this out  
(leftColumnTest.jsp) :

<%-- taglibs removed for brevity --%>
<tiles:insertDefinition name="leftColumnMain">

   <tiles:putAttribute name="main" cascade="true">
     <p>This is left column content.</p>
   </tiles:putAttribute>

   <tiles:putAttribute name="sidebar" cascade="true">
     <p>This goes in the sidebar.</p>
   </tiles:putAttribute>

</tiles:insertDefinition>

I am now finding that when I render these definitions, I get "This is  
the left column content." in place of both the "main" AND "sidebar"  
attribute. Of course, I would expect to see the main content in the  
main, left column and then the sidebar content in the other column -  
but I only see the main content. Can anyone spot my mistake? Could  
this be a bug, or am I just overlooking something simple?

It gets even weirder -- when I decide to change the order of the  
tiles:putAttribute tags in my leftColumnTest.jsp, I can produce the  
exact opposite results:

<tiles:insertDefinition name="designLeftColumnMain">

   <tiles:putAttribute name="sidebar" cascade="true">
     <p>This goes in the sidebar.</p>
   </tiles:putAttribute>

   <tiles:putAttribute name="main" cascade="true">
     <p>This is left column content.</p>
   </tiles:putAttribute>

</tiles:insertDefinition>

By putting the sidebar first, now "This goes in the sidebar" is  
rendered twice in both places. So, this leads be to believe that  
somehow something is being overwritten and that the "name" attribute  
is not really being respected.

Perhaps also this is a bug with the new cascade behavior? If anyone  
can provide me with help on how to recreate this sort of inheritance  
without using the cascade attribute, I would be very gracious! I have  
struggled for quite a few hours now trying to get this sort of  
template structure working.

Thanks in advance for any help or insight you can give...

Best,

Zach Bailey
znbailey@wethecitizens.com





Re: Tiles 2.1 Attribute Duplication/Overwriting, Possible Bug?

Posted by Antonio <an...@gmail.com>.
2008/12/8 Zach Bailey <zn...@wethecitizens.com>:
> I have logged this as a bug here:
>
> https://issues.apache.org/struts/browse/TILES-338

Yes it is definitely a bug. I filed a new one:
https://issues.apache.org/struts/browse/TILES-339

Thanks for pointing this out!
Antonio

P.S. if you want to contribute feel free to post a patch.

Re: Tiles 2.1 Attribute Duplication/Overwriting, Possible Bug?

Posted by Zach Bailey <zn...@wethecitizens.com>.
After more digging I believe I have found the bug:

In AddAttributeTag#doAfterBody:

/**
      * Save the body content of this tag (if any).
      *
      * @return It returns <code>SKIP_BODY</code>.
      */
     public int doAfterBody() {
         if (value == null && bodyContent != null) {  //bug here
             value = bodyContent.getString();
             type = "string";
         }
         return (SKIP_BODY);
     }

The value of this tag is only being updated if there is not already a  
value set. So, when this tag is used twice in succession on a page, it  
will always only use the first "value" ever set!!!

I looked back at the older Tiles 2.0.6 version we were using and the  
code is correct in that version - there is no "value == null" check.  
So, it looks as though someone added this little check at some point  
in the 2.1 release, but it seems to severely break things (at least  
for me!)

I see two ways of fixing this -

1.) Simply remove the value == null check, or if this check is in  
place for a reason,

2.) Reset value to null after each execution of the tag in doEndTag,  
or doFinally() from the TryCatchFinally interface:

http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/jsp/tagext/TryCatchFinally.html

I have logged this as a bug here:

https://issues.apache.org/struts/browse/TILES-338

Best,

Zach Bailey
znbailey@wethecitizens.com

On Dec 8, 2008, at 1:21 PM, Zach Bailey wrote:

> Hi all,
>
> I was trying some of the new Tiles 2.1 features today, specifically  
> cascading attributes. I like this new feature a lot and it seems to  
> finally solve some of the challenges I have faced with tiles in the  
> past.
>
> I am using the newest tiles release (2.1.0 beta) in conjunction with  
> Spring Web MVC.
>
> However, I have run into what seems to be a rather strange problem.  
> First, let me show you my definitions:
>
> <definition name="wrapper" template="/layouts/wrapper.jsp">
>    <put-attribute name="content" value="/common/blank.jsp"/>
> </definition>
>
> <definition name="leftColumnMain" extends="wrapper">
>    <put-attribute name="content" value="/layouts/leftColumnMain.jsp"/>
>    <put-attribute name="main" value="/common/blank.jsp"  
> cascade="true"/>
>    <put-attribute name="sidebar" value="/common/blank.jsp"  
> cascade="true"/>
> </definition>
>
> <definition name="leftColumnTest" template="/pages/ 
> leftColumnTest.jsp"/>
>
> Essentially, I am constructing a "base" layout - the wrapper - which  
> contains just the most common items (wrapper.jsp) :
>
> <%-- taglibs removed for brevity --%>
> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd 
> ">
> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
>  <head>
>    <title>Left Column Main</title>
>  </head>
>  <body>
>    <tiles:insertAttribute name="content"/>
>  </body>
> </html>
>
> which is then extended by a more specific layout which defines a 67%  
> left column and 33% right column (leftColumnMain.jsp) :
>
> <%-- taglibs removed for brevity --%>
>    <!-- Left column. -->
>    <div class="prepend-2 span-31 last">
>      <tiles:insertAttribute name="main"/>
>    </div>
>    <!-- Closes left column. -->
>
>    <!-- Right column. -->
>    <div class="prepend-1 span-14 append-1 last">
>      <tiles:insertAttribute name="sidebar"/>
>    </div>
>    <!-- Closes right column. -->
>
> which is then used for a "leaf node" page just to test all this out  
> (leftColumnTest.jsp) :
>
> <%-- taglibs removed for brevity --%>
> <tiles:insertDefinition name="leftColumnMain">
>
>  <tiles:putAttribute name="main" cascade="true">
>    <p>This is left column content.</p>
>  </tiles:putAttribute>
>
>  <tiles:putAttribute name="sidebar" cascade="true">
>    <p>This goes in the sidebar.</p>
>  </tiles:putAttribute>
>
> </tiles:insertDefinition>
>
> I am now finding that when I render these definitions, I get "This  
> is the left column content." in place of both the "main" AND  
> "sidebar" attribute. Of course, I would expect to see the main  
> content in the main, left column and then the sidebar content in the  
> other column - but I only see the main content. Can anyone spot my  
> mistake? Could this be a bug, or am I just overlooking something  
> simple?
>
> It gets even weirder -- when I decide to change the order of the  
> tiles:putAttribute tags in my leftColumnTest.jsp, I can produce the  
> exact opposite results:
>
> <tiles:insertDefinition name="designLeftColumnMain">
>
>  <tiles:putAttribute name="sidebar" cascade="true">
>    <p>This goes in the sidebar.</p>
>  </tiles:putAttribute>
>
>  <tiles:putAttribute name="main" cascade="true">
>    <p>This is left column content.</p>
>  </tiles:putAttribute>
>
> </tiles:insertDefinition>
>
> By putting the sidebar first, now "This goes in the sidebar" is  
> rendered twice in both places. So, this leads be to believe that  
> somehow something is being overwritten and that the "name" attribute  
> is not really being respected.
>
> Perhaps also this is a bug with the new cascade behavior? If anyone  
> can provide me with help on how to recreate this sort of inheritance  
> without using the cascade attribute, I would be very gracious! I  
> have struggled for quite a few hours now trying to get this sort of  
> template structure working.
>
> Thanks in advance for any help or insight you can give...
>
> Best,
>
> Zach Bailey
> znbailey@wethecitizens.com
>
>
>
>