You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tiles.apache.org by Johannes Kuhs <ex...@yahoo.de> on 2009/10/12 16:30:03 UTC

lnherit and extend attribute value

Hi all,

I was wondering if there is a way to inherit the value of an attribute and to extend it with new content. Basically, I’m looking for something like inherit=”true” for list-attributes but for normal attributes. 

Following is a quick example of what I would like to do:

Initialization in /WEB-INF/tiles-defs.xml:

<definition name=" test.definition" template="/layouts/classic.jsp">
    <put-attribute name="title" value="Initial title value" />
</definition>

Inherit and extend in /test.jsp, note inherit=”true” in the <putAttribute> tag (which does not work but I think it shows what I want to achieve):

<tiles:insertDefinition name="test.definition">
  <tiles:putAttribute name="title" inherit=”true”>
      --This text gets appended to the initial value of the title attribute
  </tiles:putAttribute>
</tiles:insertDefinition>

Now, when inserting the attribute with the following code:

<tiles:insertAttribute name="title"/>

The following title should be displayed:
Initial title value--This text gets appended to the initial value of the title attribute

Is there any way to achieve this with Tiles? Any help would be greatly appreciated!

Thanks!
John



      

Re: lnherit and extend attribute value

Posted by Antonio Petrelli <an...@gmail.com>.
2009/10/12 excurser <ex...@yahoo.de>

> Can nobody help me with this?


I wish I could, but for some reason I am not able to help when I am offline
:-D


> I get the following error:
> java.io.FileNotFoundException: ServletContext resource
> [/WEB-INF/tiles.xml] cannot be resolved to URL because it does not
> exist
>
> I don't have a file called tiles.xml but I don't know why it is even
> looking for it.
>

This is the default Tiles definition file, if you don't define yours. See:
http://tiles.apache.org/2.1/framework/config-reference.html#org.apache.tiles.definition.DefinitionsFactory.DEFINITIONS_CONFIG

Antonio

Re: lnherit and extend attribute value

Posted by excurser <ex...@yahoo.de>.
On Mon, Oct 12, 2009 at 2:55 PM, excurser <ex...@yahoo.de> wrote:
> On Mon, Oct 12, 2009 at 12:38 PM, excurser <ex...@yahoo.de> wrote:
>> On Mon, Oct 12, 2009 at 10:42 AM, Antonio Petrelli
>> <an...@gmail.com> wrote:
>>>
>>> 2009/10/12 Johannes Kuhs <ex...@yahoo.de>
>>>
>>> > I was wondering if there is a way to inherit the value of an attribute and
>>> > to extend it with new content. Basically, I’m looking for something like
>>> > inherit=”true” for list-attributes but for normal attributes.
>>> >
>>> > Following is a quick example of what I would like to do:
>>> >
>>> > Initialization in /WEB-INF/tiles-defs.xml:
>>> >
>>> > <definition name=" test.definition" template="/layouts/classic.jsp">
>>> >    <put-attribute name="title" value="Initial title value" />
>>> > </definition>
>>> >
>>> > Inherit and extend in /test.jsp, note inherit=”true” in the <putAttribute>
>>> > tag (which does not work but I think it shows what I want to achieve):
>>> >
>>> > <tiles:insertDefinition name="test.definition">
>>> >  <tiles:putAttribute name="title" inherit=”true”>
>>> >      --This text gets appended to the initial value of the title attribute
>>> >  </tiles:putAttribute>
>>> > </tiles:insertDefinition>
>>> >
>>> > Now, when inserting the attribute with the following code:
>>> >
>>> > <tiles:insertAttribute name="title"/>
>>> >
>>> > The following title should be displayed:
>>> > Initial title value--This text gets appended to the initial value of the
>>> > title attribute
>>> >
>>>
>>>
>>> You can do it with a preparer. For example, add an "auxiliar" attribute in
>>> which you put the text to add, something like:
>>>
>>> <tiles:insertDefinition name="test.definition"
>>> preparer="my.package.MyPreparer">
>>>  <tiles:putAttribute name="title-aux">
>>>     --This text gets appended to the initial value of the title attribute
>>>  </tiles:putAttribute>
>>> </tiles:insertDefinition>
>>>
>>> And in your preparer:
>>>
>>> public void execute(TilesRequestContext tilesContext,
>>>            AttributeContext attributeContext) {
>>>        String auxValue =
>>> attributeContext.getAttribute("title-aux").getValue().toString();
>>>        String originalTitle =
>>> attributeContext.getAttribute("title").getValue().toString();
>>>        attributeContext.putAttribute("title", new Attribute(originalTitle +
>>> auxValue, null);
>>>    }
>>>
>>> HTH
>>> Antonio
>>
>> Thanks for your reply, Antonio! I guess the preparer solution would
>> work but I would have to create a new preparer for every attribute
>> that I want to inherit/extend. Is there a way to have a general
>> preparer that I pass the attribute in question and the value to append
>> to?
>>
>> Thanks,
>> John
>>
>
> Following up on this. I wrote a preparer class that I can reuse for
> various attributes. However, so far I can only extend attributes that
> have a string value associated with them. If an attribute links to a
> file (e.g. /header.jsp) the the preparer adds the aux value to the
> file name instead of the actual content in the file resulting in
> something like:
>
> /header.jsp--appended text here
>
> This of course results in an error because there is not file called
> "/header.jsp--appended text here". I guess the header attribute
> content needs to be evaluated before adding the aux value. Is this
> possible within the preparer class?
>
> Thanks!
>

Can nobody help me with this? I tried evaluating the attribute content
with the following Java code but unfortunately get an error.

public class AuxiliaryPreparer implements ViewPreparer  {

	@Override
	public void execute(TilesRequestContext tilesContext,
AttributeContext attributeContext) {
		String attributeName =
attributeContext.getAttribute("aux-attribute").getValue().toString();
		String attributeValue =
attributeContext.getAttribute(attributeName).getValue().toString();
		Attribute att = attributeContext.getAttribute(attributeName);
		
		// Code to evaluate attribute
                BasicTilesContainerFactory factory = new
BasicTilesContainerFactory();
		TilesContainer container =
factory.createContainer(tilesContext.getApplicationContext());
		Attribute test = (Attribute) container.evaluate(att, tilesContext);
		
		String auxValue =
attributeContext.getAttribute("aux-value").getValue().toString();
		attributeContext.putAttribute(attributeName, new
Attribute(attributeValue + auxValue));
	}
}

I get the following error:
java.io.FileNotFoundException: ServletContext resource
[/WEB-INF/tiles.xml] cannot be resolved to URL because it does not
exist

I don't have a file called tiles.xml but I don't know why it is even
looking for it.

Anyone has an idea how to solve this problem?

Re: lnherit and extend attribute value

Posted by Antonio Petrelli <an...@gmail.com>.
2009/10/19 excurser <ex...@yahoo.de>:
> On Thu, Oct 15, 2009 at 3:05 AM, Antonio Petrelli
>> In fact there is another option.
>> Instead of putting a simple JSP as an attribute, put a definition that
>> inserts a list of attributes, as mentioned in the previous e-mail.
>> Do you think it is "elegant" enough? :-D
>
> Sorry for the late reply. I'm not sure how your suggested solution
> would look like. Could you give me an example? My goal is to have a
> "universal" way to inherit and extend the value/content of an existing
> attribute.

Starting from your original idea:

<tiles:insertDefinition name="test.definition">
 <tiles:putAttribute name="body" inherit=”true”>
    <div>This text gets appended to the initial content of the body
attribute</div>
 </tiles:putAttribute>
</tiles:insertDefinition>

It could be accomplished with this:

<tiles:insertDefinition name="test.definition">
 <tiles:putAttribute name="body">
  <tiles:definition template="/layout/listTemplate.jsp">
    <tiles:putListAttribute name="list">
       <tiles:addAttribute value="/firstElement.jsp" />
       <tiles:addAttribute value="/firstElement.jsp" />
    </tiles:putListAttribute>
  </tiles:definition>
 </tiles:putListAttribute>
</tiles:insertDefinition>

Then "listTemplate.jsp" has:

<tiles:importAttribute name="list" />
<c:forEach var="attribute" items="${list}">
  <tiles:insertAttribute value="${attribute}" />
</c:forEach>

So you create an inline definition to be used as an attribute, and
this one iterates an attribute list.

Antonio

Re: lnherit and extend attribute value

Posted by excurser <ex...@yahoo.de>.
On Thu, Oct 15, 2009 at 3:05 AM, Antonio Petrelli
<an...@gmail.com> wrote:
> 2009/10/13 Johannes Kuhs <jo...@gmail.com>:
>> Yes, the lists inheritance is great and using it would definitely
>> work. However, I would need to implement lists for all attributes in
>> order to keep the application flexible enough to handle inheritance
>> when needed without having to make changes to the Tiles definition. I
>> was hoping for a more elegant solution that somehow works with normal
>> (non-list) attributes.
>
> In fact there is another option.
> Instead of putting a simple JSP as an attribute, put a definition that
> inserts a list of attributes, as mentioned in the previous e-mail.
> Do you think it is "elegant" enough? :-D
>
> Antonio
>

Hi Antonio,

Sorry for the late reply. I'm not sure how your suggested solution
would look like. Could you give me an example? My goal is to have a
"universal" way to inherit and extend the value/content of an existing
attribute.

Thank you for all your help!

Re: lnherit and extend attribute value

Posted by Antonio Petrelli <an...@gmail.com>.
2009/10/13 Johannes Kuhs <jo...@gmail.com>:
> Yes, the lists inheritance is great and using it would definitely
> work. However, I would need to implement lists for all attributes in
> order to keep the application flexible enough to handle inheritance
> when needed without having to make changes to the Tiles definition. I
> was hoping for a more elegant solution that somehow works with normal
> (non-list) attributes.

In fact there is another option.
Instead of putting a simple JSP as an attribute, put a definition that
inserts a list of attributes, as mentioned in the previous e-mail.
Do you think it is "elegant" enough? :-D

Antonio

Re: lnherit and extend attribute value

Posted by Johannes Kuhs <jo...@gmail.com>.
On Tue, Oct 13, 2009 at 3:52 PM, Antonio Petrelli
<an...@gmail.com> wrote:
> 2009/10/13 Johannes Kuhs <jo...@gmail.com>
>
>> The following content should be inserted:
>> <div>This is the initial content</div>
>> <div>This text gets appended to the initial content of the body
>> attribute</div>
>> ...
>> In your opinion, what would be the best way to achieve this? Also,
>> what do you think about the idea of adding an "inherit" attribute for
>> the "putAttribute" tag? The same functionality already exists for
>> lists so I think it would make sense to have it for normal attributes
>> as well, wouldn't it?
>>
>
> I think that lists inheritance is great in this sense.
>
> In your templates put this:
>
> <tiles:importAttribute name="myList" />
> <c:forEach var="attribute" items="${myList}">
>  <tiles:insertAttribute value="${attribute}" />
> </c:forEach>
>
> And create in your Tiles definitions a base list attribute and an extended
> one.
>
> HTH
> Antonio
>

Yes, the lists inheritance is great and using it would definitely
work. However, I would need to implement lists for all attributes in
order to keep the application flexible enough to handle inheritance
when needed without having to make changes to the Tiles definition. I
was hoping for a more elegant solution that somehow works with normal
(non-list) attributes.

Re: lnherit and extend attribute value

Posted by Antonio Petrelli <an...@gmail.com>.
2009/10/13 Johannes Kuhs <jo...@gmail.com>

> The following content should be inserted:
> <div>This is the initial content</div>
> <div>This text gets appended to the initial content of the body
> attribute</div>
> ...
> In your opinion, what would be the best way to achieve this? Also,
> what do you think about the idea of adding an "inherit" attribute for
> the "putAttribute" tag? The same functionality already exists for
> lists so I think it would make sense to have it for normal attributes
> as well, wouldn't it?
>

I think that lists inheritance is great in this sense.

In your templates put this:

<tiles:importAttribute name="myList" />
<c:forEach var="attribute" items="${myList}">
  <tiles:insertAttribute value="${attribute}" />
</c:forEach>

And create in your Tiles definitions a base list attribute and an extended
one.

HTH
Antonio

Re: lnherit and extend attribute value

Posted by Johannes Kuhs <jo...@gmail.com>.
On Tue, Oct 13, 2009 at 3:21 AM, Antonio Petrelli
<an...@gmail.com> wrote:
> 2009/10/12 excurser <ex...@yahoo.de>
>
>> Following up on this. I wrote a preparer class that I can reuse for
>> various attributes. However, so far I can only extend attributes that
>> have a string value associated with them. If an attribute links to a
>> file (e.g. /header.jsp) the the preparer adds the aux value to the
>> file name instead of the actual content in the file resulting in
>> something like:
>>
>> /header.jsp--appended text here
>>
>> This of course results in an error because there is not file called
>> "/header.jsp--appended text here". I guess the header attribute
>> content needs to be evaluated before adding the aux value. Is this
>> possible within the preparer class?
>>
>
> Wait a minute, in this case there is something that I don't understand. What
> do you mean with "appending text" in this case?
>
> Antonio
>

Hi Antonio,

Thanks for your reply! Basically, I want to append new content to
existing content of an attribute. For example, if I had a body.jsp
file with the following content:

/body.jsp
<div>This is the initial content</div>

My configuration would look like this:

<definition name="test.definition" template="/layout.jsp">
      <put-attribute name="body"   value="/body.jsp"/>
</definition>

Now, in my test.jsp file I would like to extend the body content. Or
in other words I would like to append new content to the body.
Something like the following would be perfect but if I can somehow do
it with a preparer that would be fine too.

<tiles:insertDefinition name="test.definition">
 <tiles:putAttribute name="body" inherit=”true”>
     <div>This text gets appended to the initial content of the body
attribute</div>
 </tiles:putAttribute>
</tiles:insertDefinition>

Now, when inserting the body attribute in /layout.jsp with the following code:

<tiles:insertAttribute name="body"/>

The following content should be inserted:
<div>This is the initial content</div>
<div>This text gets appended to the initial content of the body attribute</div>

The preparer allowed me to append text but only if the attribute value
was defined as string, e.g. <put-attribute name="body"   value="My
initial value as string"/>
However, I would like to append content to a linked file as well.

In your opinion, what would be the best way to achieve this? Also,
what do you think about the idea of adding an "inherit" attribute for
the "putAttribute" tag? The same functionality already exists for
lists so I think it would make sense to have it for normal attributes
as well, wouldn't it?

Thank you very much for your help!

Re: lnherit and extend attribute value

Posted by Antonio Petrelli <an...@gmail.com>.
2009/10/12 excurser <ex...@yahoo.de>

> Following up on this. I wrote a preparer class that I can reuse for
> various attributes. However, so far I can only extend attributes that
> have a string value associated with them. If an attribute links to a
> file (e.g. /header.jsp) the the preparer adds the aux value to the
> file name instead of the actual content in the file resulting in
> something like:
>
> /header.jsp--appended text here
>
> This of course results in an error because there is not file called
> "/header.jsp--appended text here". I guess the header attribute
> content needs to be evaluated before adding the aux value. Is this
> possible within the preparer class?
>

Wait a minute, in this case there is something that I don't understand. What
do you mean with "appending text" in this case?

Antonio

Re: lnherit and extend attribute value

Posted by excurser <ex...@yahoo.de>.
On Mon, Oct 12, 2009 at 12:38 PM, excurser <ex...@yahoo.de> wrote:
> On Mon, Oct 12, 2009 at 10:42 AM, Antonio Petrelli
> <an...@gmail.com> wrote:
>>
>> 2009/10/12 Johannes Kuhs <ex...@yahoo.de>
>>
>> > I was wondering if there is a way to inherit the value of an attribute and
>> > to extend it with new content. Basically, I’m looking for something like
>> > inherit=”true” for list-attributes but for normal attributes.
>> >
>> > Following is a quick example of what I would like to do:
>> >
>> > Initialization in /WEB-INF/tiles-defs.xml:
>> >
>> > <definition name=" test.definition" template="/layouts/classic.jsp">
>> >    <put-attribute name="title" value="Initial title value" />
>> > </definition>
>> >
>> > Inherit and extend in /test.jsp, note inherit=”true” in the <putAttribute>
>> > tag (which does not work but I think it shows what I want to achieve):
>> >
>> > <tiles:insertDefinition name="test.definition">
>> >  <tiles:putAttribute name="title" inherit=”true”>
>> >      --This text gets appended to the initial value of the title attribute
>> >  </tiles:putAttribute>
>> > </tiles:insertDefinition>
>> >
>> > Now, when inserting the attribute with the following code:
>> >
>> > <tiles:insertAttribute name="title"/>
>> >
>> > The following title should be displayed:
>> > Initial title value--This text gets appended to the initial value of the
>> > title attribute
>> >
>>
>>
>> You can do it with a preparer. For example, add an "auxiliar" attribute in
>> which you put the text to add, something like:
>>
>> <tiles:insertDefinition name="test.definition"
>> preparer="my.package.MyPreparer">
>>  <tiles:putAttribute name="title-aux">
>>     --This text gets appended to the initial value of the title attribute
>>  </tiles:putAttribute>
>> </tiles:insertDefinition>
>>
>> And in your preparer:
>>
>> public void execute(TilesRequestContext tilesContext,
>>            AttributeContext attributeContext) {
>>        String auxValue =
>> attributeContext.getAttribute("title-aux").getValue().toString();
>>        String originalTitle =
>> attributeContext.getAttribute("title").getValue().toString();
>>        attributeContext.putAttribute("title", new Attribute(originalTitle +
>> auxValue, null);
>>    }
>>
>> HTH
>> Antonio
>
> Thanks for your reply, Antonio! I guess the preparer solution would
> work but I would have to create a new preparer for every attribute
> that I want to inherit/extend. Is there a way to have a general
> preparer that I pass the attribute in question and the value to append
> to?
>
> Thanks,
> John
>

Following up on this. I wrote a preparer class that I can reuse for
various attributes. However, so far I can only extend attributes that
have a string value associated with them. If an attribute links to a
file (e.g. /header.jsp) the the preparer adds the aux value to the
file name instead of the actual content in the file resulting in
something like:

/header.jsp--appended text here

This of course results in an error because there is not file called
"/header.jsp--appended text here". I guess the header attribute
content needs to be evaluated before adding the aux value. Is this
possible within the preparer class?

Thanks!

Re: lnherit and extend attribute value

Posted by excurser <ex...@yahoo.de>.
On Mon, Oct 12, 2009 at 10:42 AM, Antonio Petrelli
<an...@gmail.com> wrote:
>
> 2009/10/12 Johannes Kuhs <ex...@yahoo.de>
>
> > I was wondering if there is a way to inherit the value of an attribute and
> > to extend it with new content. Basically, I’m looking for something like
> > inherit=”true” for list-attributes but for normal attributes.
> >
> > Following is a quick example of what I would like to do:
> >
> > Initialization in /WEB-INF/tiles-defs.xml:
> >
> > <definition name=" test.definition" template="/layouts/classic.jsp">
> >    <put-attribute name="title" value="Initial title value" />
> > </definition>
> >
> > Inherit and extend in /test.jsp, note inherit=”true” in the <putAttribute>
> > tag (which does not work but I think it shows what I want to achieve):
> >
> > <tiles:insertDefinition name="test.definition">
> >  <tiles:putAttribute name="title" inherit=”true”>
> >      --This text gets appended to the initial value of the title attribute
> >  </tiles:putAttribute>
> > </tiles:insertDefinition>
> >
> > Now, when inserting the attribute with the following code:
> >
> > <tiles:insertAttribute name="title"/>
> >
> > The following title should be displayed:
> > Initial title value--This text gets appended to the initial value of the
> > title attribute
> >
>
>
> You can do it with a preparer. For example, add an "auxiliar" attribute in
> which you put the text to add, something like:
>
> <tiles:insertDefinition name="test.definition"
> preparer="my.package.MyPreparer">
>  <tiles:putAttribute name="title-aux">
>     --This text gets appended to the initial value of the title attribute
>  </tiles:putAttribute>
> </tiles:insertDefinition>
>
> And in your preparer:
>
> public void execute(TilesRequestContext tilesContext,
>            AttributeContext attributeContext) {
>        String auxValue =
> attributeContext.getAttribute("title-aux").getValue().toString();
>        String originalTitle =
> attributeContext.getAttribute("title").getValue().toString();
>        attributeContext.putAttribute("title", new Attribute(originalTitle +
> auxValue, null);
>    }
>
> HTH
> Antonio

Thanks for your reply, Antonio! I guess the preparer solution would
work but I would have to create a new preparer for every attribute
that I want to inherit/extend. Is there a way to have a general
preparer that I pass the attribute in question and the value to append
to?

Thanks,
John

Re: lnherit and extend attribute value

Posted by Antonio Petrelli <an...@gmail.com>.
2009/10/12 Johannes Kuhs <ex...@yahoo.de>

> I was wondering if there is a way to inherit the value of an attribute and
> to extend it with new content. Basically, I’m looking for something like
> inherit=”true” for list-attributes but for normal attributes.
>
> Following is a quick example of what I would like to do:
>
> Initialization in /WEB-INF/tiles-defs.xml:
>
> <definition name=" test.definition" template="/layouts/classic.jsp">
>    <put-attribute name="title" value="Initial title value" />
> </definition>
>
> Inherit and extend in /test.jsp, note inherit=”true” in the <putAttribute>
> tag (which does not work but I think it shows what I want to achieve):
>
> <tiles:insertDefinition name="test.definition">
>  <tiles:putAttribute name="title" inherit=”true”>
>      --This text gets appended to the initial value of the title attribute
>  </tiles:putAttribute>
> </tiles:insertDefinition>
>
> Now, when inserting the attribute with the following code:
>
> <tiles:insertAttribute name="title"/>
>
> The following title should be displayed:
> Initial title value--This text gets appended to the initial value of the
> title attribute
>


You can do it with a preparer. For example, add an "auxiliar" attribute in
which you put the text to add, something like:

<tiles:insertDefinition name="test.definition"
preparer="my.package.MyPreparer">
 <tiles:putAttribute name="title-aux">
     --This text gets appended to the initial value of the title attribute
 </tiles:putAttribute>
</tiles:insertDefinition>

And in your preparer:

public void execute(TilesRequestContext tilesContext,
            AttributeContext attributeContext) {
        String auxValue =
attributeContext.getAttribute("title-aux").getValue().toString();
        String originalTitle =
attributeContext.getAttribute("title").getValue().toString();
        attributeContext.putAttribute("title", new Attribute(originalTitle +
auxValue, null);
    }

HTH
Antonio