You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tiles.apache.org by Rick R <ri...@gmail.com> on 2011/08/28 07:09:00 UTC

should be super easy - but I'm screwing up using extends/nested..

This should be common so I think it would be simple.
Basic cases:
You want a plain page layout (no menu) and a standard page layout that has
the menu included.
Both pages have 'content' that should get inserted and both share a common
head section, and maybe common header and footer (basically page skeleton is
shared - just one layout should have the menu, the other one not have it.)

Here's how I thought I'd set it up:
http://pastie.org/2441904  (not showing menu.jsp)

When I try the above though I get errors
org.apache.tiles.template.NoSuchAttributeException: Attribute 'content' not
found.

(Using tiles 2.2.2)

Thanks for any help

-- 
Rick R

Re: should be super easy - but I'm screwing up using extends/nested..

Posted by Rick R <ri...@gmail.com>.
On Mon, Aug 29, 2011 at 1:49 PM, Antonio Petrelli <
antonio.petrelli@gmail.com> wrote:

> 2011/8/29 Rick R <ri...@gmail.com>
>
> > On Mon, Aug 29, 2011 at 1:38 PM, Rick R <ri...@gmail.com> wrote:
> >
> > >
> > >
> > > On Mon, Aug 29, 2011 at 1:35 PM, Antonio Petrelli <
> > > antonio.petrelli@gmail.com> wrote:
> > >
> > >>
> > >> >
> > >> > Oh, I see something like this maybe (which works, although
> definitely
> > >> more
> > >> > verbose):
> > >> >
> > >> > <definition name="signup" extends="base.definition">
> > >> >  <put-attribute name="pageBody">
> > >> > <definition templateExpression="/WEB-INF/layouts/plainBody.jsp">
> > >> >  <put-attribute name="content"
> > >> value="/WEB-INF/views/signup/signup.jsp"/>
> > >> > </definition>
> > >> >  </put-attribute>
> > >> > </definition>
> > >> >
> > >>
> > >> It's not verbose, it's right.
> > >>
> > >>
> > >
> > >
> > > Ok so should that be preferred over using 'cascade=true' (which I'm
> > > thinking your suggesting it is.)
> > >
> > > I got that above down to a little more clear with the following (used
> > > extends on pageBody to plain.body so that template definition could be
> > > defined in a more common place.)
> > >
> > > <definition name="signup" extends="base.definition">
> > > <put-attribute name="pageBody">
> > >  <definition extends="plain.body">
> > > <put-attribute name="content"
> value="/WEB-INF/views/signup/signup.jsp"/>
> > >  </definition>
> > > </put-attribute>
> > > </definition>
> > >
> > >
> >
> > It is more verbose though but I prefer to do what is 'right' and won't
> get
> > me into trouble later. But here are the two side by side:
> >
> > BEFORE using cascade, most page definitions using the plain layout would
> > look like:
> >
> > <definition name="signup" extends="plainLayout">
> > <put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"
> > cascade="true"/>
> > </definition>
> >
> >
> > NOT using cascade and the nested definition:
> >
> > <definition name="signup" extends="base.definition">
> >  <put-attribute name="pageBody">
> > <definition extends="plain.body">
> >  <put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"/>
> > </definition>
> >  </put-attribute>
> > </definition>
> >
>
> There is no "right" thing to do. Cascade attributes have one problem: they
> are cascaded to every nested definition. This way you cannot have two
> sibling nested definitions that share the same attribute names. However, if
> it is not your case, cascade attributes allow an easier to read XML file.
>
> My suggestion is to *use cascade attributes* and use anonymous nested
> definitions to override any attributes with the same names as the cascaded
> ones, if you have this case.
>
> Antonio
>

Thanks you helped a lot!

-- 
Rick R

Re: should be super easy - but I'm screwing up using extends/nested..

Posted by Antonio Petrelli <an...@gmail.com>.
2011/8/29 Rick R <ri...@gmail.com>

> On Mon, Aug 29, 2011 at 1:38 PM, Rick R <ri...@gmail.com> wrote:
>
> >
> >
> > On Mon, Aug 29, 2011 at 1:35 PM, Antonio Petrelli <
> > antonio.petrelli@gmail.com> wrote:
> >
> >>
> >> >
> >> > Oh, I see something like this maybe (which works, although definitely
> >> more
> >> > verbose):
> >> >
> >> > <definition name="signup" extends="base.definition">
> >> >  <put-attribute name="pageBody">
> >> > <definition templateExpression="/WEB-INF/layouts/plainBody.jsp">
> >> >  <put-attribute name="content"
> >> value="/WEB-INF/views/signup/signup.jsp"/>
> >> > </definition>
> >> >  </put-attribute>
> >> > </definition>
> >> >
> >>
> >> It's not verbose, it's right.
> >>
> >>
> >
> >
> > Ok so should that be preferred over using 'cascade=true' (which I'm
> > thinking your suggesting it is.)
> >
> > I got that above down to a little more clear with the following (used
> > extends on pageBody to plain.body so that template definition could be
> > defined in a more common place.)
> >
> > <definition name="signup" extends="base.definition">
> > <put-attribute name="pageBody">
> >  <definition extends="plain.body">
> > <put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"/>
> >  </definition>
> > </put-attribute>
> > </definition>
> >
> >
>
> It is more verbose though but I prefer to do what is 'right' and won't get
> me into trouble later. But here are the two side by side:
>
> BEFORE using cascade, most page definitions using the plain layout would
> look like:
>
> <definition name="signup" extends="plainLayout">
> <put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"
> cascade="true"/>
> </definition>
>
>
> NOT using cascade and the nested definition:
>
> <definition name="signup" extends="base.definition">
>  <put-attribute name="pageBody">
> <definition extends="plain.body">
>  <put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"/>
> </definition>
>  </put-attribute>
> </definition>
>

There is no "right" thing to do. Cascade attributes have one problem: they
are cascaded to every nested definition. This way you cannot have two
sibling nested definitions that share the same attribute names. However, if
it is not your case, cascade attributes allow an easier to read XML file.

My suggestion is to *use cascade attributes* and use anonymous nested
definitions to override any attributes with the same names as the cascaded
ones, if you have this case.

Antonio

Re: should be super easy - but I'm screwing up using extends/nested..

Posted by Rick R <ri...@gmail.com>.
On Mon, Aug 29, 2011 at 1:38 PM, Rick R <ri...@gmail.com> wrote:

>
>
> On Mon, Aug 29, 2011 at 1:35 PM, Antonio Petrelli <
> antonio.petrelli@gmail.com> wrote:
>
>>
>> >
>> > Oh, I see something like this maybe (which works, although definitely
>> more
>> > verbose):
>> >
>> > <definition name="signup" extends="base.definition">
>> >  <put-attribute name="pageBody">
>> > <definition templateExpression="/WEB-INF/layouts/plainBody.jsp">
>> >  <put-attribute name="content"
>> value="/WEB-INF/views/signup/signup.jsp"/>
>> > </definition>
>> >  </put-attribute>
>> > </definition>
>> >
>>
>> It's not verbose, it's right.
>>
>>
>
>
> Ok so should that be preferred over using 'cascade=true' (which I'm
> thinking your suggesting it is.)
>
> I got that above down to a little more clear with the following (used
> extends on pageBody to plain.body so that template definition could be
> defined in a more common place.)
>
> <definition name="signup" extends="base.definition">
> <put-attribute name="pageBody">
>  <definition extends="plain.body">
> <put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"/>
>  </definition>
> </put-attribute>
> </definition>
>
>

It is more verbose though but I prefer to do what is 'right' and won't get
me into trouble later. But here are the two side by side:

BEFORE using cascade, most page definitions using the plain layout would
look like:

<definition name="signup" extends="plainLayout">
<put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"
cascade="true"/>
</definition>


NOT using cascade and the nested definition:

<definition name="signup" extends="base.definition">
 <put-attribute name="pageBody">
<definition extends="plain.body">
 <put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"/>
</definition>
 </put-attribute>
</definition>

Re: should be super easy - but I'm screwing up using extends/nested..

Posted by Rick R <ri...@gmail.com>.
On Mon, Aug 29, 2011 at 1:35 PM, Antonio Petrelli <
antonio.petrelli@gmail.com> wrote:

>
> >
> > Oh, I see something like this maybe (which works, although definitely
> more
> > verbose):
> >
> > <definition name="signup" extends="base.definition">
> >  <put-attribute name="pageBody">
> > <definition templateExpression="/WEB-INF/layouts/plainBody.jsp">
> >  <put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"/>
> > </definition>
> >  </put-attribute>
> > </definition>
> >
>
> It's not verbose, it's right.
>
>


Ok so should that be preferred over using 'cascade=true' (which I'm thinking
your suggesting it is.)

I got that above down to a little more clear with the following (used
extends on pageBody to plain.body so that template definition could be
defined in a more common place.)

<definition name="signup" extends="base.definition">
<put-attribute name="pageBody">
 <definition extends="plain.body">
<put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"/>
 </definition>
</put-attribute>
</definition>



-- 
Rick R

Re: should be super easy - but I'm screwing up using extends/nested..

Posted by Antonio Petrelli <an...@gmail.com>.
2011/8/29 Rick R <ri...@gmail.com>

> On Mon, Aug 29, 2011 at 1:26 PM, Rick R <ri...@gmail.com> wrote:
>
> >
> >
> > On Mon, Aug 29, 2011 at 1:13 PM, Antonio Petrelli <
> > antonio.petrelli@gmail.com> wrote:
> >
> >> 2011/8/29 Rick R <ri...@gmail.com>
> >>
> >> > What is driving me crazy though is "How would you accomplish this
> >> "without"
> >> > using cascade='true' ?" (In fact I think the application I'll
> eventually
> >> > have to integrate with is using a very old version of Tiles (1?) that
> >> > doesn't have cascade? )
> >> >
> >> > You mentioned above "Either you define a new definition that uses
> >> > plainBody.jsp... ," which I 'think'  I did in the above pastie with
> >> > "plain.body" and 'standard.body' definitions, but if I give it an
> >> attribute
> >> > of content which I expected to be overridden, it's not overridden. As
> an
> >> > example in the below I'll end up with "foo bar 2" as the content
> instead
> >> of
> >> > the 'signup' definition put-attribute content (if I remove cascade =
> >> true
> >> > on
> >> > the signup put-attribute .)
> >> >
> >> > <definition name="plain.body"
> >> > templateExpression="/WEB-INF/layouts/plainBody.jsp">
> >> >     <put-attribute name="content" value="foo bar 2"/> <!-- never
> really
> >> > overridden ??? -->
> >> > </definition>
> >> >
> >>
> >> Probably, anonymous nested definitions best fits your needs:
> >>
> >>
> http://tiles.apache.org/2.2/framework/tutorial/advanced/nesting-extending.html#Anonymous_nested_definitions
> >>
> >>
> >
> >
> > I tried that at first, but didn't have any luck. Here is how I set it up,
> > but the problem is "content" in plainBody.jsp is not overridden in
> pageBody.
> > You'll see OVERRIDE ME show up, and without that put-attribute it
> complains
> > that it's needed.
> >
> >
> > <definition name="plainLayout"
> > templateExpression="/WEB-INF/layouts/page.jsp">
> > <put-attribute name="title" value="My App" />
> >  <put-attribute name="pageBody">
> > <definition templateExpression="/WEB-INF/layouts/plainBody.jsp">
> >  <put-attribute name="content" value="OVERRIDE ME"/>
> > </definition>
> >  </put-attribute>
> > </definition>
> >
> > <definition name="signup" extends="plainLayout">
> >  <put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"/>
> > </definition>
> >
> >
> >
> >
>
> Oh, I see something like this maybe (which works, although definitely more
> verbose):
>
> <definition name="signup" extends="base.definition">
>  <put-attribute name="pageBody">
> <definition templateExpression="/WEB-INF/layouts/plainBody.jsp">
>  <put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"/>
> </definition>
>  </put-attribute>
> </definition>
>

It's not verbose, it's right.

Antonio

Re: should be super easy - but I'm screwing up using extends/nested..

Posted by Rick R <ri...@gmail.com>.
On Mon, Aug 29, 2011 at 1:26 PM, Rick R <ri...@gmail.com> wrote:

>
>
> On Mon, Aug 29, 2011 at 1:13 PM, Antonio Petrelli <
> antonio.petrelli@gmail.com> wrote:
>
>> 2011/8/29 Rick R <ri...@gmail.com>
>>
>> > What is driving me crazy though is "How would you accomplish this
>> "without"
>> > using cascade='true' ?" (In fact I think the application I'll eventually
>> > have to integrate with is using a very old version of Tiles (1?) that
>> > doesn't have cascade? )
>> >
>> > You mentioned above "Either you define a new definition that uses
>> > plainBody.jsp... ," which I 'think'  I did in the above pastie with
>> > "plain.body" and 'standard.body' definitions, but if I give it an
>> attribute
>> > of content which I expected to be overridden, it's not overridden. As an
>> > example in the below I'll end up with "foo bar 2" as the content instead
>> of
>> > the 'signup' definition put-attribute content (if I remove cascade =
>> true
>> > on
>> > the signup put-attribute .)
>> >
>> > <definition name="plain.body"
>> > templateExpression="/WEB-INF/layouts/plainBody.jsp">
>> >     <put-attribute name="content" value="foo bar 2"/> <!-- never really
>> > overridden ??? -->
>> > </definition>
>> >
>>
>> Probably, anonymous nested definitions best fits your needs:
>>
>> http://tiles.apache.org/2.2/framework/tutorial/advanced/nesting-extending.html#Anonymous_nested_definitions
>>
>>
>
>
> I tried that at first, but didn't have any luck. Here is how I set it up,
> but the problem is "content" in plainBody.jsp is not overridden in pageBody.
> You'll see OVERRIDE ME show up, and without that put-attribute it complains
> that it's needed.
>
>
> <definition name="plainLayout"
> templateExpression="/WEB-INF/layouts/page.jsp">
> <put-attribute name="title" value="My App" />
>  <put-attribute name="pageBody">
> <definition templateExpression="/WEB-INF/layouts/plainBody.jsp">
>  <put-attribute name="content" value="OVERRIDE ME"/>
> </definition>
>  </put-attribute>
> </definition>
>
> <definition name="signup" extends="plainLayout">
>  <put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"/>
> </definition>
>
>
>
>

Oh, I see something like this maybe (which works, although definitely more
verbose):

<definition name="signup" extends="base.definition">
 <put-attribute name="pageBody">
<definition templateExpression="/WEB-INF/layouts/plainBody.jsp">
 <put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"/>
</definition>
 </put-attribute>
</definition>

Re: should be super easy - but I'm screwing up using extends/nested..

Posted by Rick R <ri...@gmail.com>.
On Mon, Aug 29, 2011 at 1:13 PM, Antonio Petrelli <
antonio.petrelli@gmail.com> wrote:

> 2011/8/29 Rick R <ri...@gmail.com>
>
> > What is driving me crazy though is "How would you accomplish this
> "without"
> > using cascade='true' ?" (In fact I think the application I'll eventually
> > have to integrate with is using a very old version of Tiles (1?) that
> > doesn't have cascade? )
> >
> > You mentioned above "Either you define a new definition that uses
> > plainBody.jsp... ," which I 'think'  I did in the above pastie with
> > "plain.body" and 'standard.body' definitions, but if I give it an
> attribute
> > of content which I expected to be overridden, it's not overridden. As an
> > example in the below I'll end up with "foo bar 2" as the content instead
> of
> > the 'signup' definition put-attribute content (if I remove cascade = true
> > on
> > the signup put-attribute .)
> >
> > <definition name="plain.body"
> > templateExpression="/WEB-INF/layouts/plainBody.jsp">
> >     <put-attribute name="content" value="foo bar 2"/> <!-- never really
> > overridden ??? -->
> > </definition>
> >
>
> Probably, anonymous nested definitions best fits your needs:
>
> http://tiles.apache.org/2.2/framework/tutorial/advanced/nesting-extending.html#Anonymous_nested_definitions
>
>


I tried that at first, but didn't have any luck. Here is how I set it up,
but the problem is "content" in plainBody.jsp is not overridden in pageBody.
You'll see OVERRIDE ME show up, and without that put-attribute it complains
that it's needed.


<definition name="plainLayout"
templateExpression="/WEB-INF/layouts/page.jsp">
<put-attribute name="title" value="My App" />
 <put-attribute name="pageBody">
<definition templateExpression="/WEB-INF/layouts/plainBody.jsp">
 <put-attribute name="content" value="OVERRIDE ME"/>
</definition>
 </put-attribute>
</definition>

<definition name="signup" extends="plainLayout">
 <put-attribute name="content" value="/WEB-INF/views/signup/signup.jsp"/>
</definition>



-- 
Rick R

Re: should be super easy - but I'm screwing up using extends/nested..

Posted by Antonio Petrelli <an...@gmail.com>.
2011/8/29 Rick R <ri...@gmail.com>

> What is driving me crazy though is "How would you accomplish this "without"
> using cascade='true' ?" (In fact I think the application I'll eventually
> have to integrate with is using a very old version of Tiles (1?) that
> doesn't have cascade? )
>
> You mentioned above "Either you define a new definition that uses
> plainBody.jsp... ," which I 'think'  I did in the above pastie with
> "plain.body" and 'standard.body' definitions, but if I give it an attribute
> of content which I expected to be overridden, it's not overridden. As an
> example in the below I'll end up with "foo bar 2" as the content instead of
> the 'signup' definition put-attribute content (if I remove cascade = true
> on
> the signup put-attribute .)
>
> <definition name="plain.body"
> templateExpression="/WEB-INF/layouts/plainBody.jsp">
>     <put-attribute name="content" value="foo bar 2"/> <!-- never really
> overridden ??? -->
> </definition>
>

Probably, anonymous nested definitions best fits your needs:
http://tiles.apache.org/2.2/framework/tutorial/advanced/nesting-extending.html#Anonymous_nested_definitions

Antonio

Re: should be super easy - but I'm screwing up using extends/nested..

Posted by Rick R <ri...@gmail.com>.
On Mon, Aug 29, 2011 at 5:02 AM, Antonio Petrelli <
antonio.petrelli@gmail.com> wrote:

> 2011/8/28 Rick R <ri...@gmail.com>
>
> > Here's how I thought I'd set it up:
> > http://pastie.org/2441904  (not showing menu.jsp)
> >
>
> You are trying to put an attribute that belongs to an included page
> (plainBody.jsp) in a definition that includes it.
> Either you define a new definition that uses plainBody.jsp (ideally, any
> JSP
> page that has a tiles:insertAttribute should be used as a template of a
> definitio), or use:
> cascade="true"
> in <put-attribute>
>
> Beware, cascade is powerful, but it is dangerous if there are places that
> require the same attribute names.
>
>


Thanks for replying Antonio. Grasping this is slow going :) Using
cascade="true' definitely helped. I cleaned things up a little bit and below
is the new tiles definition page, which is actually working!

Here is my new relevant info (you'll see cascade = true on the content put
attribute calls):
http://pastie.org/2449471

What is driving me crazy though is "How would you accomplish this "without"
using cascade='true' ?" (In fact I think the application I'll eventually
have to integrate with is using a very old version of Tiles (1?) that
doesn't have cascade? )

You mentioned above "Either you define a new definition that uses
plainBody.jsp... ," which I 'think'  I did in the above pastie with
"plain.body" and 'standard.body' definitions, but if I give it an attribute
of content which I expected to be overridden, it's not overridden. As an
example in the below I'll end up with "foo bar 2" as the content instead of
the 'signup' definition put-attribute content (if I remove cascade = true on
the signup put-attribute .)

<definition name="plain.body"
templateExpression="/WEB-INF/layouts/plainBody.jsp">
     <put-attribute name="content" value="foo bar 2"/> <!-- never really
overridden ??? -->
</definition>

Thanks again for all your help. I'd think my situation is a common one. In
fact here is an example of a common situation

https://img.skitch.com/20110829-q8iby8jayc76qif2drcdrrwhpk.jpg

There should be an easy way to not have to redefine the <html><head>..
//common stuff</head>   ... <div id="footer">..</div></body></html>  section
for all three layouts. The body content obviously varies. I have things
working with cascade="true" so I'm content there - but I'm still curious how
it would be done without it?

Re: should be super easy - but I'm screwing up using extends/nested..

Posted by Antonio Petrelli <an...@gmail.com>.
2011/8/28 Rick R <ri...@gmail.com>

> Here's how I thought I'd set it up:
> http://pastie.org/2441904  (not showing menu.jsp)
>

You are trying to put an attribute that belongs to an included page
(plainBody.jsp) in a definition that includes it.
Either you define a new definition that uses plainBody.jsp (ideally, any JSP
page that has a tiles:insertAttribute should be used as a template of a
definitio), or use:
cascade="true"
in <put-attribute>

Beware, cascade is powerful, but it is dangerous if there are places that
require the same attribute names.

Antonio