I'm new to struts. I'm trying to implement tiles as described in this article:
Reuse Tiles and Simplify UI
By James Holmes
In the article a centralized xml file is used to describe the inheritenace between pages. For some reason I can't make this work.
The tiles are working like this:
<tiles:insert page="/template.jsp" flush="true">
<tiles:put name="title" value="Sample Page Title2" />
<tiles:put name="header" value="/pages/_header.jsp" />
<tiles:put name="left" value="/pages/_left.jsp" />
<tiles:put name="body" value="/pages/_body.jsp" />
<tiles:put name="footer" value="/pages/_footer.jsp" />
</tiles:insert>
..when added in another page. So this way the current page inherits the layout from the template.jsp. But the code goes in each page.
I want it all in the tiles-defs.xml file.
***
Another thing concerning tiles...
Is it possible to use tiles in several levels? Like if the body part should add pieces of common code.
Thank you in advance.
-
Struts tiles (13 messages)
- Posted by: Daniel Jakobsson
- Posted on: November 09 2004 23:18 EST
Threaded Messages (13)
- Struts tiles by Duncan Mills on November 10 2004 08:45 EST
- Struts tiles by Rich Hill on November 10 2004 16:00 EST
-
Struts tiles by Daniel Jakobsson on November 10 2004 08:01 EST
-
Struts tiles by Per Joergensen on November 11 2004 03:06 EST
-
Struts tiles by Daniel Jakobsson on November 11 2004 09:57 EST
-
Struts tiles by Per Joergensen on November 12 2004 03:12 EST
-
Struts tiles by Daniel Jakobsson on November 13 2004 01:03 EST
-
Struts tiles by Per Joergensen on November 15 2004 03:11 EST
-
Struts tiles by Daniel Jakobsson on November 15 2004 09:43 EST
- Struts tiles by Per Joergensen on November 15 2004 04:37 EST
-
Struts tiles by Daniel Jakobsson on November 15 2004 09:43 EST
-
Struts tiles by Per Joergensen on November 15 2004 03:11 EST
-
Struts tiles by Daniel Jakobsson on November 13 2004 01:03 EST
-
Struts tiles by Per Joergensen on November 12 2004 03:12 EST
-
Struts tiles by Daniel Jakobsson on November 11 2004 09:57 EST
-
Struts tiles by Per Joergensen on November 11 2004 03:06 EST
-
Struts tiles by Daniel Jakobsson on November 10 2004 08:01 EST
- Struts tiles by Rich Hill on November 10 2004 16:00 EST
- Check out sitemesh by Derek Adams on November 11 2004 16:53 EST
- sitemesh by Daniel Jakobsson on November 11 2004 22:01 EST
- Database driven tiles by Oleg Timofeyev on December 22 2004 03:09 EST
-
Struts tiles[ Go to top ]
- Posted by: Duncan Mills
- Posted on: November 10 2004 08:45 EST
- in response to Daniel Jakobsson
Here's a simple tiles-defs.xml that works:<?xml version="1.0" encoding="windows-1252" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration//EN"
"http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd">
<tiles-definitions>
<definition name="tiles.mainLayout" path="/templates/template.jsp">
<put name="title" value="Tiles Header title" />
<put name="header" value="/tiles/header.jsp" />
<put name="footer" value="/tiles/footer.jsp" />
<put name="body" value="/tiles/body.jsp" />
</definition>
<definition name="tiles.subclassedLayout.page" extends="tiles.mainLayout" >
<put name="title" value="A subclassed Page" />
<put name="body" value="/tiles/body2.jsp" />
</definition>
</tiles-definitions> -
Struts tiles[ Go to top ]
- Posted by: Rich Hill
- Posted on: November 10 2004 16:00 EST
- in response to Duncan Mills
Replace
<tiles:insert page="/template.jsp" flush="true">
with
<definition name="someName" path="/template.jsp">
and
</tiles:insert>
with
</definition>
Dunan Mills' response is right on the money.
Also, yes you can do tiles in levels. Instead of
<put name="body" value="/pages/_body.jsp"/>
use
<put name="body" value="XYZ"/>
then, add a new tile definition for the body with a name of XYZ. -
Struts tiles[ Go to top ]
- Posted by: Daniel Jakobsson
- Posted on: November 10 2004 20:01 EST
- in response to Rich Hill
Thank you both for replying.
Maybe it's obvious, but how do I call this inherited page?
Template:
http://localhost/testApp/template.jsp
Inherited:
http://localhost/testApp/someName
I suppose I don't have to create a page like before, since there is no url in the inherited definition. -
Struts tiles[ Go to top ]
- Posted by: Per Joergensen
- Posted on: November 11 2004 03:06 EST
- in response to Daniel Jakobsson
Hallo Daniel
You cannot call a tile directly from the browser you'll have to do it by using a actionforward.
something like the following;
package com.example.struts;
public MyAction extends ... {
public void execute(...) {
return mapping.findActionForward("myTile");
}
}
Your Struts definition should contain something like;
<action path="/myAction"
type="com.example.struts.MyAction >
<forward name="myTile" path="tile"/>
</action>
Hope this will help you.
/Per -
Struts tiles[ Go to top ]
- Posted by: Daniel Jakobsson
- Posted on: November 11 2004 21:57 EST
- in response to Per Joergensen
Thanks Per. I can't get it to work though. This is what I have:
(I used findForward, since I didn't find findActionForward in the ActionMappingClass.)
package test;
import org.apache.struts.action.*;
import javax.servlet.http.*;
public class MyAction extends org.apache.struts.action.Action {
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
return mapping.findForward("myTile");
}
}
In the struts-config:
<action path="/myAction"
type="test.MyAction" >
<forward name="myTile" path="Template"/>
</action>
In the tiles-def:
<definition name="someName" path="/_template.jsp">
<put name="title" value="Standard Title" />
<put name="header" value="/pages/_header.jsp" />
<put name="left" value="/pages/_left.jsp" />
<put name="body" value="/pages/_body.jsp" />
<put name="footer" value="/pages/_footer.jsp" />
</definition>
<definition name="Template" extends="someName">
<put name="title" value="Another Title" />
</definition>
Anyway, does this mean I have to create a new class for every new tile?
Thanks!
/Daniel -
Struts tiles[ Go to top ]
- Posted by: Per Joergensen
- Posted on: November 12 2004 03:12 EST
- in response to Daniel Jakobsson
Thanks Per. I can't get it to work though. This is what I have:(I used findForward, since I didn't find findActionForward in the ActionMappingClass.)package test;import org.apache.struts.action.*;import javax.servlet.http.*;public class MyAction extends org.apache.struts.action.Action { public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { return mapping.findForward("myTile"); }}In the struts-config:<action path="/myAction" type="test.MyAction" > <forward name="myTile" path="Template"/></action>In the tiles-def:<definition name="someName" path="/_template.jsp"> <put name="title" value="Standard Title" /> <put name="header" value="/pages/_header.jsp" /> <put name="left" value="/pages/_left.jsp" /> <put name="body" value="/pages/_body.jsp" /> <put name="footer" value="/pages/_footer.jsp" /></definition><definition name="Template" extends="someName"> <put name="title" value="Another Title" /></definition>Anyway, does this mean I have to create a new class for every new tile?Thanks!/Daniel
---
If the tile doesn't work try using this naming convention:
Call your tile definitions something like;
.<someName>.[.something-more]
and do the reference in the actionforward by this name.
Another problem could be that you don't use the TileRequestProcessor, but the default StrutsRequestProcessor.
No you don't have to make a new class for each tile;
example
-------
In the struts-config:
<action path="/myAction"
type="test.MyAction" >
<forward name="newView" path=".newView.product"/>
<forward name="editView" path=".editView.product"/>
</action>
In the tiles-def:
<definition name="someName" path="/_template.jsp">
<put name="title" value="Standard Title" />
<put name="header" value="/pages/_header.jsp" />
<put name="left" value="/pages/_left.jsp" />
<put name="body" value="/pages/_body.jsp" />
<put name="footer" value="/pages/_footer.jsp" />
</definition>
<definition name=".newView.product" extends="someName">
<put name="title" value="New Product" />
</definition>
<definition name=".editView.product" extends="someName">
<put name="title" value="Edit Product" />
</definition>
In this case you can control in your action which action forward to choose and then this tile will be presented.
The classic example is that you have one Action that saves the Product, dependent on whether its a new Product the title for the tile should show New, or Edit if the Product already exists.
Nb. Sorry for the findActionForward(), I wrote the example in this editor :-).
/Per -
Struts tiles[ Go to top ]
- Posted by: Daniel Jakobsson
- Posted on: November 13 2004 13:03 EST
- in response to Per Joergensen
Thanks a lot for your help, it's really appreciated!
I copied what you suggested to the tiles-defs and struts-config files.
The MyAction class was changed to:
..
public ActionForward execute(...) {
return mapping.findForward("newView");
}
..
And I then (after recompiling and restarting the app), I tried to call the tile using these urls:
http://localhost/testApp/myAction
http://localhost/testApp/newView
The result was "The requeste resource is not available." in both cases.
Oh and I use the TileRequestProcessor;
<controller processorClass="org.apache.struts.tiles.TilesRequestProcessor"/>
Could it be that the tiles-defs are not loaded for some reason? I added this plug-in in the struts-config:
<plug-in className="org.apache.struts.tiles.TilesPlugin" >
<set-property property="definitions-config"
value="/WEB-INF/tiles-defs.xml" />
<set-property property="moduleAware" value="true" />
</plug-in>
The Tomcat log file says:
13/11/2004 15:47:33 org.apache.struts.tiles.TilesPlugin initDefinitionsFactory
INFO: Tiles definition factory loaded for module ''.
I tried to cut the module-aware tag, no difference.
Again, thanks a lot for your help. -
Struts tiles[ Go to top ]
- Posted by: Per Joergensen
- Posted on: November 15 2004 03:11 EST
- in response to Daniel Jakobsson
Thanks a lot for your help, it's really appreciated!I copied what you suggested to the tiles-defs and struts-config files.The MyAction class was changed to:..public ActionForward execute(...) { return mapping.findForward("newView");}..And I then (after recompiling and restarting the app), I tried to call the tile using these urls:http://localhost/testApp/myActionhttp://localhost/testApp/newViewThe result was "The requeste resource is not available." in both cases.Oh and I use the TileRequestProcessor;<controller processorClass="org.apache.struts.tiles.TilesRequestProcessor"/>Could it be that the tiles-defs are not loaded for some reason? I added this plug-in in the struts-config:<plug-in className="org.apache.struts.tiles.TilesPlugin" > <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" /> <set-property property="moduleAware" value="true" /></plug-in>The Tomcat log file says:13/11/2004 15:47:33 org.apache.struts.tiles.TilesPlugin initDefinitionsFactoryINFO: Tiles definition factory loaded for module ''.I tried to cut the module-aware tag, no difference.Again, thanks a lot for your help.
hallo
Your setup look correct for the tile part..
You might have forgotten to prefix your struts call with
.do like this ??
http://localhost/testApp/myAction.do
http://localhost/testApp/newView.do
Another thing could be that the actionforward should reference tile with .names.
public ActionForward execute(...) {
return mapping.findForward("newView");
}
..
struts def.
<forward name="newView" path=".myTile"/>
..
Tiles-defs.
<definition name=".default" path="/_template.jsp">
<put name="title" value="Standard Title" />
<put name="header" value="/pages/_header.jsp" />
<put name="left" value="/pages/_left.jsp" />
<put name="body" value="/pages/_body.jsp" />
<put name="footer" value="/pages/_footer.jsp" />
</definition>
<definition name=".myTile" extends=".default">
<put name="title" value="Another Title" />
</definition>
/Per -
Struts tiles[ Go to top ]
- Posted by: Daniel Jakobsson
- Posted on: November 15 2004 09:43 EST
- in response to Per Joergensen
Hey, it's working! Thanks a lot!
I wasn't aware that .do is necessary in the url.
http://localhost/testApp/myAction.do
So for a set of functions I can use the same action class (saveStuff).
Suppose I have one template and 20 pages that should inherit it. I want to call each page through a different url, like
../page1.do, ../page2.do, etc. In the example;
http://localhost/testApp/newView.do
http://localhost/testApp/editView.do.
Can I still use the same action class for all?
I suppose I have to create one class for each different url, unless I use parameters. -
Struts tiles[ Go to top ]
- Posted by: Per Joergensen
- Posted on: November 15 2004 16:37 EST
- in response to Daniel Jakobsson
Hey, it's working! Thanks a lot!I wasn't aware that .do is necessary in the url.http://localhost/testApp/myAction.doSo for a set of functions I can use the same action class (saveStuff).Suppose I have one template and 20 pages that should inherit it. I want to call each page through a different url, like ../page1.do, ../page2.do, etc. In the example; http://localhost/testApp/newView.dohttp://localhost/testApp/editView.do.Can I still use the same action class for all?I suppose I have to create one class for each different url, unless I use parameters.
Im glad to hear that it works, I think you will be very happy using tiles.
You can use the same action class for many templates, but each url is connected to one actionform which identifies your form input data, so the best strategy if you want to avoid having many action making simple CRUD operation is to use a DispatchAction (I think one is included with Struts).
/Per -
Check out sitemesh[ Go to top ]
- Posted by: Derek Adams
- Posted on: November 11 2004 16:53 EST
- in response to Daniel Jakobsson
For an alternative to tiles, check out sitemesh here. I have used both and sitemesh is (IMHO) much more powerful and easier to use.
Derek -
sitemesh[ Go to top ]
- Posted by: Daniel Jakobsson
- Posted on: November 11 2004 22:01 EST
- in response to Derek Adams
Thanks for the tip, I'll look into it.
For now I'll probably use tiles though.
/Daniel -
Database driven tiles[ Go to top ]
- Posted by: Oleg Timofeyev
- Posted on: December 22 2004 03:09 EST
- in response to Daniel Jakobsson
I have been using tiles for a few months now and found that using urlController allows for much more advanced applications. Wow, I love it. However, I do not see a lot of articles/tutorials about it. Maybe there is a reason why its not used that often? I for once find it very powerful to pick a layout to use from database as well as pull all the components from it.
I did run into an interesting issue lately, my urlController is getting pretty fat (hey maybe that’s reason why hehe) but I wanted to call different Actions based on the data requested from this controller and cant find a way to do it. Is there a way to execute an Action from urlController and than come back to executing the rest of urlController?
Thanks