Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Composing Apache Tiles 2 layout from many templates

I'm building the web application with Spring 3 and Tiles 2.2. I've put following layout definition:

<tiles-definitions>  
<definition name="default" template="/WEB-INF/layouts/default.jspx">  
<put-attribute name="header" value="main.header" />  
<put-attribute name="top_menu" value="/WEB-INF/views/top_menu.jspx" />  
<put-attribute name="left_column" value="main2.left_column" />  
<put-attribute name="main_column" value="main2.main_column" />  
<put-attribute name="footer" value="/WEB-INF/views/footer.jspx" />  
</definition> 

<definition name="main2.main_column" template="/WEB-INF/layouts/double_column/main_column.jspx">  
</definition>

<definition name="main2.left_column" template="/WEB-INF/layouts/left_column.jspx">  
        <put-attribute name="profile_menu" value="/WEB-INF/views/userprofile/userdetails.jspx" />  
        <put-attribute name="common_menu" value="/WEB-INF/views/menu.jspx" />  
      </definition>  
</tiles-definitions>

In WEB-INF/layouts/default.jspx

<div id="main_page" >   
    <tiles:insertAttribute name="left_column"/>    
    <tiles:insertAttribute name="main_column"/>   
        <div id="footer" >  
<tiles:insertAttribute name="footer" ignore="true"/>  
                </div>  
            </div>  

Now in /WEB-INF/layouts/double_column/main_column.jspx i have:

<tiles:insertAttribute name="body"/>  

Requested path view.xml is defined as following:

<tiles-definitions>  
    <definition extends="default" name="secure/createAccount/*">  
        <put-attribute name="body" value="/WEB-INF/views/secure/createAccount/{1}.jspx"/>  
    </definition>  
</tiles-definitions>

and error is:

org.apache.tiles.template.NoSuchAttributeException: Attribute 'body' not found.
    org.apache.tiles.template.DefaultAttributeResolver.computeAttribute(DefaultAttributeResolver.java:49)
    org.apache.tiles.template.InsertAttributeModel.resolveAttribute(InsertAttributeModel.java:187)
    org.apache.tiles.template.InsertAttributeModel.start(InsertAttributeModel.java:107)
    org.apache.tiles.jsp.taglib.InsertAttributeTag.doTag(InsertAttributeTag.java:306)
    org.apache.jsp.WEB_002dINF.layouts.double_005fcolumn.main_005fcolumn_jspx._jspx_meth_tiles_005finsertAttribute_005f0(main_005fcolumn_jspx.java:79)
    org.apache.jsp.WEB_002dINF.layouts.double_005fcolumn.main_005fcolumn_jspx._jspService(main_005fcolumn_jspx.java:54)

If i put "body" directly to the default template it works, but thing is I want have my template bricks being reusable by many layouts, not only default one and i dont want to copy all formating to each template definition using main_column

Please advice

like image 239
Random Avatar asked Dec 08 '25 15:12

Random


1 Answers

As the exception tells you the definition of main_column has not attribute body. Your second definition says that it is an your root definition and not of main_column. By default there is no such thing like attributes inheritance or bubbling. Hence the children don't know anything about the attributes of their parents and vice versa. Their are two solutions for your problem:

You can add the attribute cascade="true" to your attribute definition. That lets the attribute cascade to the child definitions (see cascaded attributes)

You could use nested definitions:

<tiles-definitions>  
  <definition extends="default" name="secure/createAccount/*">  
    <put-attribute name="main_column">
      <definition template="/WEB-INF/layouts/double_column/main_column.jspx">
        <put-attribute name="body" value="/WEB-INF/views/secure/createAccount/{1}.jspx"/>  
      </definition>
    </put-attribute>
  </definition>  
</tiles-definitions>

(see nesting definitions)

like image 129
gregor Avatar answered Dec 11 '25 19:12

gregor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!