Tiles 3 how to reference another definition in put

2019-09-16 14:52发布

问题:

I'd like to be able to define a base definition, where I can inherit a list of styles and scripts. then define a page definition that inherits base definition, and adds page specific styles and scripts. Is this possible -or am I not thinking about this in the right way? I would have thought this to be a fairly basic idea.

base definitions

<tiles-definitions>
    <!-- base styles -->
    <definition name="base.styles" >
        <put-list-attribute name="styles" cascade="true" >
            <add-attribute value="/view/common/jquery-ui-theme-base-v1.12.1.css" />
        </put-list-attribute>
    </definition>
    <!-- base scripts -->
    <definition name="base.scripts" >
        <put-list-attribute name="scripts" cascade="true" >
            <add-attribute value="https://code.jquery.com/jquery-3.1.0.min.js" />
            <add-attribute value="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" />
        </put-list-attribute>
    </definition>
    <!-- base definition -->
    <definition name="base.definition" template="/WEB-INF/page/defaultLayout.jsp" >
        <put-attribute name="title" />
        <put-attribute name="styles" value="base.styles.styles" cascade="true" />
        <put-attribute name="header" value="/WEB-INF/page/common/header.jsp" />
        <put-attribute name="body" />
        <put-attribute name="scripts" value="base.scripts.scripts" cascade="true" />
        <put-attribute name="footer" value="/WEB-INF/page/common/footer.jsp" />
    </definition>
</tiles-definitions>

note the values of the put-attribute match the names of the definitions above them. (my guess is this isn't correct)

page specific definitions

<tiles-definitions>
    <!-- page specific styles -->
    <definition name="samplePage.styles" extends="base.styles" >
        <put-list-attribute name="styles" inherit="true" >
            <add-attribute value="/view/page/samplePage/samplePageStyles.css" />
        </put-list-attribute>
    </definition>
    <!-- page specific scripts -->
    <definition name="samplePage.scripts" extends="base.scripts" >
        <put-list-attribute name="scripts" inherit="true" >
            <add-attribute value="/view/page/samplePage/samplePageScript.js" />
        </put-list-attribute>
    </definition>
    <!-- page specific definition -->
    <definition name="samplePage" extends="base.definition" >
        <put-attribute name="title" value="Sample Page" />
        <put-attribute name="styles" value="samplePage.styles" cascade="true" />
        <put-attribute name="body" value="/WEB-INF/page/samplePage/samplePageBody" />
        <put-attribute name="scripts" value="samplePage.scripts" cascade="true" />
    </definition>
</tiles-definitions>

again -note the values of the put-attribute match the names of the definitions above them. (probably not correct?)

I'm currently getting an IllegalArgumentException

Caused by: java.lang.IllegalArgumentException: Cannot convert samplePage.styles of type class java.lang.String to class org.apache.tiles.Attribute
at com.sun.el.lang.ELSupport.coerceToType(ELSupport.java:428)
at com.sun.el.ExpressionFactoryImpl.coerceToType(ExpressionFactoryImpl.java:85)
... 104 more

It appears as if the put-attributes for the styles and scripts are not picking up the definitions of the same name above them... but I'm not sure what to do to correct it. Any ideas?

回答1:

To answer the question how to reference another definition in put-attribute, this appears to be fairly easy with jsp components such as the following (note the definition, and the 'type' attribute):

<definition name="default.header" template="/WEB-INF/page/common/header.jsp" />

... then elsewhere...

<put-attribute name="header" type="definition" value="default.header" />

However, it doesn't look like this can be done with resources such as stylesheets and scripts, as they don't translate back to an actual template. So, I reworked my base-definition as follows, which still allows me to have 'global' resources, as well as 'page-specific' resources. Also allows me to write the jsp components once, define them once, and reference them many times.

common definitions (tiles.common.xml)

<tiles-definitions>
    <definition name="default.header" template="/WEB-INF/page/common/header.jsp" />
    <definition name="default.footer" template="/WEB-INF/page/common/footer.jsp" />

    [... all the other common components...]

</tiles-definitions>

base definition (tiles.base.xml)

<tiles-definitions>
    <definition name="base.definition" template="/WEB-INF/page/baseLayout.jsp" >
        <put-attribute name="title" type="string" />
        <put-attribute name="header" type="definition" value="default.header" />
        <put-attribute name="body" />
        <put-attribute name="footer" type="definition" value="default.footer" />
        <put-list-attribute name="styles" inherit="true" >
            <add-attribute value="/view/common/jquery-ui-theme-base-v1.12.1.css" />

            [... other styles common to all pages...]

        </put-list-attribute>
        <put-list-attribute name="scripts" inherit="true" >
            <add-attribute value="https://code.jquery.com/jquery-3.1.0.min.js" />
            <add-attribute value="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" />

            [... other scripts common to all pages...]

        </put-list-attribute>
    </definition>
</tiles-definition>

page specific definition (tiles.samplePage.xml)

<tiles-definitions>
    <definition name="samplePage" extends="base.definition" >
        <put-attribute name="title" value="Sample Page" />
        <put-attribute name="body" value="/WEB-INF/page/samplePage.jsp" />
        <put-list-attribute name="styles" inherit="true" >
            <add-attribute value="/view/pages/samplePage.css" />

            [... other page specific styles ...]

        </put-list-attribute>
        <put-list-attribute name="scripts" inherit="true" >
            <add-attribute value="/view/pages/samplePage.js" />

            [... other page specific scripts ...]

        </put-list-attribute>
    </definition>
</tiles-definition>