tiles-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mck <m...@wever.org>
Subject Re: howto delegate to other definitions ?
Date Tue, 09 Feb 2010 16:42:13 GMT

> First of all, version of Tiles? 

I'm working with trunk (2.2.2-SNAPSHOT), via Spring-web
(3.0.1-SNAPSHOT), made possible with the patch included in
http://jira.springframework.org/browse/SPR-6097

Thanks for a quick response.

> >    <definition name="vertical.motor" template="/WEB-INF/blank.jsp"> 
> >        <put-attribute name="description" value="/WEB-INF/tiles/vertical/motor/description.jsp"
cascade="true"/> 
> >    </definition> 
> >... 
> 
> The description attribute is available from "vertical.motor" 
> definition to all *included* definitions, not definitions that include 
> it. 

I'm starting to see that. Was hoping that insertDefinition, or
importAttribute (given that the attribute is a definition), would make
it possible to access the internal attributes from a different
definition.

> I suppose that to accomplish what you want to do is using a preparer. 

That doesn't quite fit the big picture for me :-(
What i'm after is delegation, or injection, of definitions in addition
to the supported extension.

To explain, i got is a number of "global" wildcarded definitions like this:

    <!-- sub-vertical definition -->
    <definition name="WILDCARD:*.*.*" extends="{1}.{2}" template="/WEB-INF/tiles/templates/[{3}|{2}|{1}]_template.jsp">
        <put-attribute name="body" value="/WEB-INF/tiles/vertical/[{3}|{2}|{1}]/content_new.jsp"
cascade="true"/>
        ...        
        <!-- definition injection -->
        <put-list-attribute name="definition-injection" inherit="true">
            <add-attribute value="subvertical.{3}" type="string"/>
        </put-list-attribute>
    </definition>

    <!-- vertical definition -->
    <definition name="WILDCARD:*.*" extends="{1}" template="/WEB-INF/tiles/templates/[{2}|{1}]_template.jsp">
        <put-attribute name="body" value="/WEB-INF/tiles/vertical/[{2}|{1}]/content_new.jsp"
cascade="true"/>
        ...
        <!-- Dynamic definition injection -->
        <put-list-attribute name="definition-injection">
            <add-attribute value="vertical.{2}" type="string"/>
        </put-list-attribute>
    </definition>

Then in additional tiles-*.xml (that individual developer teams are free to edit) definitions
like:

    <!-- motor definition that is injected into the real definition -->
    <definition name="vertical.motor">
        <put-attribute name="motor.description" value="/WEB-INF/tiles/vertical/motor/description.jsp"/>
        <put-attribute name="motor.equipment" value="/WEB-INF/tiles/vertical/motor/equipment.jsp"/>
    </definition>

    <!-- car definition that is injected into the real definition -->
    <definition name="subvertical.car">
        <put-attribute name="car.something" value="/WEB-INF/tiles/vertical/car/something.jsp"/>
    </definition>

By overriding the DefinitionsFactory like:

            private static final String DEF_INJECTION = "definition-injection";
            @Override
            public Definition getDefinition(String name, TilesRequestContext tilesContext)
{
                Definition def = super.getDefinition(name, tilesContext);
                if(null != def){
                    def = new Definition(super.getDefinition(name, tilesContext));
                    Attribute defList = def.getLocalAttribute(DEF_INJECTION);
                    if(null != defList){
                        if(defList instanceof ListAttribute){
                            List<Attribute> list = (List<Attribute>) defList.getValue();
                            for(Attribute inject : list){
                                injectDefinition((String) inject.getValue(), def, tilesContext);
                            }
                        }
                    }
                }
                return def;
            }
            private void injectDefinition(String fromName, Definition to, TilesRequestContext
cxt){
                Definition from = super.getDefinition(fromName, cxt);
                for(String attrName : from.getLocalAttributeNames()){
                    to.putAttribute(attrName, from.getLocalAttribute(attrName), true);
                }
            }

these "definition-injection" definitions are injected at run-time.
For example the spring controller returns a View("advert.motor.car").
This matches the definition with hierarchy:

 "WILDCARD:*.*.*" --> "WILDCARD:*.*" --> "WILDCARD:*"

but each definition has in addition "a sideways delegation" so-to-speak,
like:

 "WILDCARD:*.*.*" --> "subvertical.{3}"
    |
    v
 "WILDCARD:*.*"   --> "vertical.{2}"
    |
    v
 "WILDCARD:*"


I've got this working as explained, but was hoping there was an existing
and easier way to achieve it all. Is there?

~mck

ps the "[{3}|{2}|{1}]" syntax is provided by a custom
TemplateAttributeRenderer, it returns the found template looking first
for {3}, then for {2}, and finally for {1}.


-- 
"People only get lost in thought because it is unfamiliar territory."
Paul Fix 
| semb.wever.org | sesat.no | finn.no |

Mime
View raw message