Sometimes it is useful to have a structured page with, say, a structured body. Typically, there is a main layout (for example, the "classic" layout) and the body is made of certain number of sections. In this case, nesting a definition (the one for the body) inside another definition (the main layout) can be useful.
Tiles supports nesting definitions natively. One way of using nested definitions is creating a named "subdefinition" and using it as an attribute. For example:
<definition name="myapp.homepage.body" template="/layouts/three_rows.jsp"> <put-attribute name="one" value="/tiles/headlines.jsp" /> <put-attribute name="two" value="/tiles/topics.jsp" /> <put-attribute name="one" value="/tiles/comments.jsp" /> </definition> <definition name="myapp.homepage" template="/layouts/classic.jsp"> <put-attribute name="title" value="Tiles tutorial homepage" /> <put-attribute name="header" value="/tiles/banner.jsp" /> <put-attribute name="menu" value="/tiles/common_menu.jsp" /> <put-attribute name="body" value="myapp.homepage.body" /> <put-attribute name="footer" value="/tiles/credits.jsp" /> </definition>
The myapp.homepage.body definition will be put inside the myapp.homepage, by putting it inside its body attribute. You will be seeing the definition one inside the other.
What you can do with named subdefinitions can be done with nested anonymous definitions. The above example can be rewritten in:
<definition name="myapp.homepage.body" template="/layouts/three_rows.jsp"> <put-attribute name="one" value="/tiles/headlines.jsp" /> <put-attribute name="two" value="/tiles/topics.jsp" /> <put-attribute name="one" value="/tiles/comments.jsp" /> </definition> <definition name="myapp.homepage" template="/layouts/classic.jsp"> <put-attribute name="title" value="Tiles tutorial homepage" /> <put-attribute name="header" value="/tiles/banner.jsp" /> <put-attribute name="menu" value="/tiles/common_menu.jsp" /> <put-attribute name="body"> <definition template="/layouts/three_rows.jsp"> <put-attribute name="one" value="/tiles/headlines.jsp" /> <put-attribute name="two" value="/tiles/topics.jsp" /> <put-attribute name="one" value="/tiles/comments.jsp" /> </definition> </put-attribute> <put-attribute name="footer" value="/tiles/credits.jsp" /> </definition>
The anonymous definition put under the "body" attribute can be used only by the surrounding definition. Moreover, you can nest a definition into a nested definition, with the desired level of depth.
Attributes defined into a definition can be cascaded to be available to all nested definitions and templates. For example the sample definition detailed above can be rewritten this way:
<definition name="myapp.homepage" template="/layouts/classic.jsp"> <put-attribute name="title" value="Tiles tutorial homepage" /> <put-attribute name="header" value="/tiles/banner.jsp" /> <put-attribute name="menu" value="/tiles/common_menu.jsp" /> <put-attribute name="body" value="/layouts/three_rows.jsp" /> <put-attribute name="footer" value="/tiles/credits.jsp" /> <put-attribute name="one" value="/tiles/headlines.jsp" cascade="true" /> <put-attribute name="two" value="/tiles/topics.jsp" cascade="true" /> <put-attribute name="one" value="/tiles/comments.jsp" cascade="true" /> </definition>
The template of myapp.homepage.body definitionhas been used as the body attribute in the myapp.homepage definition. All of the attributes of myapp.homepage.body has been then moved as attributes of myapp.homepage definition, but with the addition of the "cascade" flag.
You can extend definitions like a Java class. The concepts of abstract definition, extension and override are available.
<definition name="myapp.page.common" template="/layouts/classic.jsp"> <put-attribute name="header" value="/tiles/banner.jsp" /> <put-attribute name="menu" value="/tiles/common_menu.jsp" /> <put-attribute name="footer" value="/tiles/credits.jsp" /> </definition>
<definition name="myapp.homepage" extends="myapp.page.common"> <put-attribute name="title" value="Tiles tutorial homepage" /> <put-attribute name="body" value="myapp.homepage.body" /> </definition>
In this case, the header, menu and footer are inherited from the myapp.page.common definition, while the rest is defined inside the "concrete" definition.
<definition name="myapp.homepage.alternate" extends="myapp.homepage" template="/layouts/alternate.jsp" />
The definition has the same attributes, but its template changed. The result is that the content is the same, but the layout is different.
<definition name="myapp.homepage.customer" extends="myapp.homepage"> <put-attribute name="menu" value="/tiles/common_menu_for_customers.jsp" /> </definition>
In this case, the page will have the same appearance as the myapp.homepage definition, but its menu subpage is different.