Author : Cedric Dumoulin
Date : 14 Nov. 2000
Table of Content
Tiles framework was previously called Components framework. This tutorial was written for Components. It is totally compatible with Tiles, only name ?components? has to be changed to ?tiles?.
Rewriting of this document is a work in progress. If you want to use it today, be indulgent, and change yourself ?components? to ?tiles?.
This tutorial shows you how to write and use Tiles to define a Web site. Use this tutorial to learn the basic skills you'll need to develop a Web site and to learn about some of the features of the Tiles Framework.
In this tutorial, you will create a fictitious web site, with pages illustrating Tiles features : basic page, portal page, definitions, i18n.
This tutorial cover the view part of the UI, it doesn?t cover the model and controller part of the MVC 2 model.
Along the way, you'll learn how to perform the following tasks:
In order to run examples of this tutorial, you need to install a JSP server, like Tomcat. You also need the Tiles Library, the Struts Library, and some jar files from the Jakarta Commons project. If you have downloaded Tiles binary distribution, you already got all needed files.
We suppose that you have some basic knowledge of web development, JSP and JSP tags.
Examples of this tutorial are in the Tiles distribution file.
However, we advise you to write yourself the examples. For that, you can create a directory under the web server webapps directory (call it tutorial), and put all your files and sub-directories under this directory.
In order to avoid rewriting configurations files, you can copy the complete WEB-INF directory from the tutorial to your directory.
Your first page is a simple page that will be improved later in this tutorial.
Your first page look like the following picture :
It is divided in header, footer, menu and body. Such division identifies our main tiles :
These tiles are assembled together using a layout or template. This layout is also a tile. As layouts are often used, there exists a library of layouts. But, in this tutorial, you will learn how to write simple layout.
Once you have your main tiles and your layout, you need to set up your web page main entrance (i.e. : define the web page that will process the http request). This can simply be done in a jsp file.
Starting from the page main entrance, we can draw a tree of tiles, like the following :
4.2 Write Tiles
Covered topics : write simple tiles; the ?html link? problem.
Your header will contain the company logo.
Copy directory tutorial/images from the distribution tutorial directory to your examples root directory.
Create a new blank file, and save it under tutorial/common/header.jsp.
Edit your new file, and place your images, as in following :
You can note that images path is absolute (starting with ?/?). You need to use an absolute path because this component can be included from pages residing at different places, not always at your site root.
220.127.116.11 The ?html link? problem
Using simple absolute path work fine if your web site is placed directly at the root of your domain name (i.e. : at www.mycompany.com). If your web site is under a subdomain (i.e. : at www.mycompany.com/my_site), as it is often the case, you need to prefix this path with the subdomain name (my_site). In order to have a portable site, you can retrieve the subdomain name from the http request.
Our component becomes :
It is a good habit to prefix absolute links used in client side (html links) by the subdomain name, retrieved from the http request. In this tutorial, you will always prefix html links with subdomain name.
If you also plan to use Struts, you can use the <link> or <img> tag defined in html tags library.
The footer contains company copyrights.
Create a new file, and save it under tutorial/common/footer.jsp.
Write copyrights notice, as in following :
The menu contains links to other pages. For now, you just write a simple menu. You will create more sophisticated menus later in this tutorial.
Create a new file, and save it under tutorial/basic/menu.jsp.
Now, you can create your menu : create a table, with tree rows. Normally, each row contains a link to a page. Here, only first row contains link to the main page.
Your code should looks like the following :
The body is the active part of your pages. For now, you will develop a simple body writing the classic sentence ?Hello the World?. You will develop other bodies later.
Create a new file, and save it under tutorial/basic/hello.jsp.
In your file, write ?Hello the World?.
The code should looks like the following :
Covered topics : passing parameters, basic layout understanding, assembling tiles in layout, insert tag mechanism understanding. Retrieving parameter values.
Now, you will assemble your tiles. For that, you will develop a tile taking in charge the layout, and including previously developed tiles where you want them to reside. This tile can be seen as a Template.
In order for your layout tile to be reusable, you will pass it tiles to be inserted as parameters.
To pass parameters to the tile that will do the layout, you write something like that :
Or like the following, which is the same, but looks like more familiar to people already using Struts Template :
Create a new file, write previous line of code and save it under tutorial/basicPage.jsp.
The first line instructs the web server to use the tiles tag library. It also specifies that all tags from this library will start with the prefix tiles.
The tag itself specifies the tiles page to insert : /tutorial/basic/myLayout.jsp. You will develop this tile in a few moments. We pass parameters to this tile, each one is identified by a name. The value can be of any type. Here we use hard-coded strings.
First, create a new file, and save it under tutorial/basic/myLayout.jsp.
In this file, create a table reflecting your layout, as describe in Plan your components and main layout.
The code looks like this :
Note : This layout contains <html>, <head> and <body> tags. This tile is used to define the html page.
4.3.3 Insert Tiles
Now, you will insert (include) tiles by using special tags.
Put the following code at the beginning of your page :
This instruct jsp processor to use the
special tags library
Next, you can insert your tiles by using following tag :
This tag inserts a tile whose name is taken from the value of the attribute ?body?. It is why you must use attribute=??.
Do the same for each of your tile. The code should looks like :
Your layout tile will be used several times. But you certainly want a different title for each page using this layout. For that, you will pass the page title as a parameter. In the layout, you extract the title from tile?s parameters, and put the value in the correct place :
Tag getAsString (formerly getAttribute) retrieves the value of a tile?s attribute, and write it directly as a string. So, the tag will be replaced by the value you passed to the tile.
Following is the complete code for your first layout tile :
You can test your page by starting your web server, and pointing to your newly created page ?basicPage.jsp?.
Note : your configuration files must be set correctly before starting the web server. For now, you can simply copy the entire WEB-INF directory in your tutorial directory.
Covered topics : Reuse layouts.
Assembling of tiles is often done in the same way. It is possible to develop some basic layouts and reuse them inside a web site, or even from site to site. Provided examples come with some layouts : classic layout, portal (columns), vertical boxes.
You will first learn how to reuse such layouts. In a later chapter, you will learn how to build your own layouts.
The most common layout for a page is the header / menu / body / footer layout. We provide one of this layout under /tutorial/layout/classicLayout.jsp. You can use it in place of your previously defined layout : simply change the name of included tile in basicPage.jsp :
Note that there is no change in the passed parameters. In the same way, you can change the way a layout component laid sub-components. If well designed, you can change all site look and feel simply by changing main layout component !
Covered topics : use of layout inside tiles, list as parameter to a tile.
Here, you will learn how to build a portal by assembling tiles.
A portal is made of tiles, ?stacked ? into columns. Portal page use the layout common to all site. So, you only need to define the body of your portal page.
This body uses a tile that lay sub tiles in columns. You need to pass as parameters the number of columns you want, and a list of tiles for each column.
5.2.1 Prepare Portal Tiles
First, you need to define some tiles to assemble in your page. You can define your own tiles, or copy the one defined in the tutorial (under tutorial/portal/*).
Copy tiles from directory ?portal/*? in your tutorial directory (keep the sub directory ?portal? ).
5.2.2 Assemble Portal Tiles
Create a new file and save it under tutorial/portal/portalBody.jsp.
Include the portal layout (called /tutorial/layout/columnsLayout.jsp), passing it the requested number of columns, and a list of tiles for each column. List names must be ?listX?, where ?X? is the index of the list, starting at zero.
Your code looks like following :
In this code, you declare three attributes : one variable and two lists. Values are added to the list in the specified order. Here, you add sub-tiles URLs. It is possible to add definitions name instead (see definitions).
You can now include your portal body in any tiles. Preferably, you will include it in a page using the main layout.
Create the page in a new file called /tutorial/portalPage.jsp :
Note that you use ?classicLayout.jsp? rather than your ?myLayout.jsp?. Both layouts are nearly the same, except than classicLayout include a style sheet used in the entire site.
Check result by pointing your browser on the page.
We often need to put tiles one under the others. The vertical boxes layout (/tutorial/layout/vboxLayout.jsp) does exactly that. You pass it a list of tiles, and it laid them vertically.
As an example, we will improve the menu : it will now be made of three tiles : one showing an image, one providing links to pages and one providing links to a tile writing sources.
5.3.1 Assemble Tiles
Create a new file and save it under /tutorial/common/menu.jsp. In this file, include the vboxLayout tile, and pass it a list with sub-tiles URLs.
Your code should looks like :
The vboxLayout tile requires one parameter called ?componentList?. It is a list of URLs referencing sub-tiles to insert. Of course, you need to have such tiles.
Following is the code of this tile :
Following is the code of this tile :
This tile uses another tile, submenu.jsp. This later takes a list of items and a list of links as parameters, and shows them in a menu fashion. You will learn later how to write the submenu tile. For now, copy it from the original /tutorial/common directory to your /tutorial/common/submenu.jsp
Following is the code of this tile :
This tile uses another tile, menuSrc.jsp. This later takes a list of pages URLs, and shows links pointing to a tile writing source of an URL. You will learn later how to write needed tiles. For now, copy them (viewSrc.jsp; viewSrcBody.jsp, menuViewSrc.jsp) from the original /tutorial/common directory to your /tutorial/common/.
You can now use your new menu.
Edit the /tutorial/portalPage.jsp , and specify the path to your new menu :
Check result by pointing your browser to the page.
You have certainly notice that the vertical boxes example require a lot of small tiles whose only purpose is to declare parameters used by other tiles. In the next chapter, we will see how to remove such tiles, replacing them by definitions declared in a central file.
Note 1 : In previous Components versions, Definitions was called Instances.
Note 2 : It is now possible to define a Definition into a jsp page (not yet described in tutorial. See /test/testDefinition.jsp for an example).
A tile definition is a tile associated with parameters, and identified by a definition name.
Definitions allow :
Definitions are declared in a description file in XML. You can place this file anywhere and call it as you want, but its preferred place is under WEB-INF/componentDefinitions.xml. There is a DTD for this file, located in lib/components-config.dtd. Actually, parser doesn?t use the dtd to validate file.
Create a new file, and save it under WEB-INF/componentDefinitions.xml (You can erase any existing file with this name if any).
Write or copy following line of code :
This declares a definition called myFirstDefinition, using component /layout/classicLayout.jsp.
Definition declaration syntax is nearly the same as including a component with parameters. You must specify a name, and the path of the component that you defined. After that, you can add all parameters that you need. Here, we pass all required parameters, but it is possible to pass only some of them.
To use a definition in a web page, you include it with the insert tag.
You will see later that you can also use definitions as component parameters or as forward in the struts-config file.
Create a new file, and save it under definitionPage.jsp.
Write following lines :
These lines include specified component definition.
Web server look in its definitions list declaration for requested definition, and then call this definition.
In order to work, the definitions list must be initialized. You will learn how in a few moment.
You can override any parameters of a definition. For example, override the title parameter as following :
In fact, overriding a parameter as the same syntax as passing parameter.
Overriding parameter is often used to specify the body and title used by a new page.
Overriding parameter can also be done in the definition description file.
Before using definitions in a page, you need to load the definitions list in your application. Using a special servlet, extending the Struts ?action servlet?, can do this.
Edit the WEB-INF/web.xml file, and add following lines :
If you already have a servlet called ?action?, replace it with the one provided.
These lines declare a servlet called action, which is a definition of ?s1.struts.component.ActionComponentServlet?. This servlet extends Struts servlet by adding definitions capabilities. All struts parameters still work. There is additional optional parameters :
Now you can try your first definition page : restart the web server, and point your browser on definitionPage.jsp.
Warning : in the current version (010429), the definition description file is not automatically reloaded. This mean that you have to restart the server each time you change the description file. This will change in future versions.
A definition name can be used as parameter of a component, as long as this parameter is used to include something.
As an example, we will rewrite our previous portal page entirely by using definitions, with some passed as component parameters.
We first need to declare the portal definition, and then describe the menu and the portal body.
Definition declaration is done in the componentDefinitions.xml file. Declare the portal definition as following :
You can note that values of menu and body attributes are not URLs. They are definition names that we now need to define.
You can write the portal body definition as following :
This declares a definition of columnsLayout, with specified parameters. You can see that the syntax is similar as the declaration in the jsp file.
You will now rewrite menu as definitions. Remember : the main menu is made of logo menu, links menu and sources menu. Links menu uses submenu.jsp components, and sources menu uses menuViewSrc.jsp component.
Following is the code of definition :
Again, definition declaration is similar to declaration in the jsp file. But now, you don?t need the intermediate component anymore.
Following is the code of definition :
Here, we include the menuLogo.jsp file. Note that there are no parameters.
In fact it is possible to specify directly the file to use in the menu.main definition.
Another possibility is to define a component taking an image URL as parameter, and showing this image. Try to write it as an example !
Here again, definition code is similar as component code :
If you want to add entry, you need to add entry name, and corresponding URL.
Following is an abstract of the menu source definition :
You can add entry by adding its URL.
You are now ready to try your definition :
Write a JSP page including it, restart the server, and point your browser on the page.
Create a new file and save it under index.jsp :
You can do inheritance with definitions. This means that a definition can extends another definition, inheriting all attributes defined in the parent. Of course, child can overload any of the attributes.
As an example, you will extend the mainLayout definition, changing the body and the title. As body, you will use one of the portal components.
Your definition declaration looks like following :
You declare a definition, specifying its name, and the name of the definition that it extends. For that, you use extends=?definitionName?.
To try your extended definition, you need to create a web page including the definition. Create a new file and save it under extendedDefinition.jsp :
Definitions can be used as forward targets in the struts-config.xml file.
As an example, you will write a page with two buttons : success and failure. A form, associated to a Struts action, surrounds these buttons. The Struts action forwards to a logical name, success or failure.
You first need to write the form page. In fact, you will write the body, declare a definition, and write a page including this definition.
Create a new file and save it under forward/forwardBody.jsp :
This file contains a form with two buttons. You can use Struts tag form instead.
Declare a new definition including this body :
Write a page including this definition.
Create a new file and save it under /strutsForward.jsp :
You can try the page, but you still need to write the Struts action before submitting !
Struts action is a java class. Following is an abstract of the code of this class :
You can find complete code in documentation. For now, you have nothing particular to do, because compile class is included in components.jar.
You need to setup the Struts configuration file, in order to register the new action.
Add something like following in the action.xml or struts-config.xml :
If you use the struts-config.xml file, you need to put the global forward between <global-forwards> and </global-forwards>.
You can note that the forwards? paths specified definitions, rather than URLs.
Now you need to declare these two definitions.
Declare the success and failure definitions :
Write the corresponding bodies.
Create a new file and save it under /forward/successBody.jsp :
Create a new file and save it under /forward/failureBody.jsp :
Note that you don?t need to write pages including the success or failure definitions. Inclusion is done directly by the value returned by Struts action.
You can now try the new page. Restart the web server to reload definitions.
Point your browser on /strutsForward.jsp, and click on one button.
It?s now time to write more complex components. You have already used such components : classicLayout, submenu, viewSrc, ?
Such components are intelligent components containing some logic. You can put logic inside a component, as long as it is UI logic. You must avoid some business logic inside a component.
Covered topics : dynamic component, passing list as parameters, using list in components, using conditional tags.
Submenu takes as parameters : a list of items, a list of links corresponding to items, a title and value of selected item. It shows the title, followed by items. When you click on an item, you follow corresponding link. If selected value correspond to one item, this item is disable (no link).
Create a new file and save it under common/submenu.jsp.
First, you will show the list of items. Create a table with two rows. In the first row, write the title parameter. Around the second row, place ?iterate? tags, and write the iteration value in the row.
Code is as following :
You start by importing components attributes (items, links, title, selected) to the page context. This allows you to use such attributes.
Then, you show the title, and you iterate on each items. As you can iterate only on one list with the iteration tag, you need to iterate yourself on second list. It is why you declare an ?Iterator i?.
One specification is to disable link on selected item.
You need to check if an item is equal to ?selected? value, and write appropriate value.
Your code become :
The specification says that title and selected are optional. So, you need to check their presence. For that, you use Struts tags ?present? and ?notPresent?.
Check for title presence, and show it only if present.
Check for selected presence, and declare a dummy selected variable if not.
Your code must be changed to :
[to do 001115]
You can check code in /common/menuViewSrc.jsp. Nearly the same as submenu.
Covered topics : use of sub-Tiles in a Tile.
In this chapter you will learn how to write Tiles that can be reused more than one time in a page. As example, we develop an ?address? Tile, included two times in an ?invoice?.
Problems come when you have input fields in the address tile : how to have two different names for input while using the same tile description ? As a solution, you will prefix input field names by a prefix pass as parameter to the Tile.
Second difficulty is how to retrieve data to be shown in the address Tile ? Here, you will pass Java bean (Java object), and deal with it in the address component. Data to be edited must be accessible from the bean using the prefix and the property name/
All Java classes are already written and compiled for you. You can check sources from the Tile Library distribution, under directory src/org/apache/struts/example/invoice.
7.3.1 Address Tile
Create a new file and save it under invoice/editAddress.jsp.
In this file, create a table with two columns : one containing fields names, one containing html input fields. Use Struts tags ?text? for the input fields.
Following is the code for this tile :
This Tile takes two parameters :
First, we retrieve parameters, then we compute the prefix if any.
Names of generated html input tags will be ?beanName.fieldname?. This will allows to retrieve value in the controller.
7.3.2 Invoice Tile
Create a new file and save it under invoice/editInvoice.jsp.
This invoice contains two times the address tile, and two html input fields :
You insert an address Tile where you want it to reside. You pass it its name, and the Java bean containing values. This bean comes from ?invoiceForm? object, and is retrieved using getter method. Don?t forget to provide two different name for each Tile inserted !
You can use your edit invoice form in a page using main layout.
Create a new file and save it under invoice/index.jsp.
If you don't like to use scriplets (<%= ?%>) inside your tags, you can extend Struts tags to add a 'prefix' attribute. This solution was used in an older example accessible in the invoice directory (editAddress2.jsp and editInvoice2.jsp).
As example, we provide an extended version of tag text, available in library "extensions.tld".
8 Internationalization (i18n)
Covered topics : use of i18n description files.
Components Library allows having different copies of a component, each one suited for a language or locale. When the component is included, the appropriate copy is chosen.
Now come the problems : where to put copies ? There are two main approaches :
Each approach has advantage and drawbacks, depending of your application. So we have chosen to let yourself determine where to place copies.
The Component i18n mechanism let you write different definitions file, one for each language. Choice of the appropriate definition file is done following the same rules as the Java properties bundle, adding language suffix to file name. You must write a default definition file, and you can write copies of this file, each copy name suffixed by the language code.
In a copy, you don?t need to rewrite all definition descriptions : you just rewrite definitions that differ. All copies automatically inherit from the default definition file.
This i18n mechanism is intended to be a complement of the key-properties bundle provided by Struts. You should use it when you have big components to internationalize. If you have only small sentences or words, use the key mechanism. Both mechanisms can be used in one site.
Let see how all this work on an example : you will add a new menu giving choice between several languages. When you change language, the menu change, displaying only the other possible languages. Titles of some pages also change. This is not a real i18n example : it just illustrates how we can do.
You will start by writing the new menu, and add it to the main menu. This menu is linked to a Struts action switching the user Locale object. Then, you will write copies of the definitions file.
This menu shows different available languages. You will write it has a definition using a submenu component :
You specify the item names, and the corresponding URLs. Here, items are linked to a Struts action switching the current language.
Don?t forget to add the new sub-menu to the main menu definition :
The action Java code is as follow :
It could certainly be improved, but it is not the purpose of this tutorial. It simply checks requested language, and set the user locale attribute appropriately (under the name defined by Action.LOCALE_KEY).
You can now try your pages, but nothing new happens because you need to define localized copies of definitions description file.
You can write a definitions file for each of your languages. Remember that you must have a default file (with no language code suffix).
It is better to start from a new empty file, as you don?t need to rewrite all definitions.
Create a new file and save it under WEB-INF/componentDefinitions_fr.xml.
Copy the menu.lang definition from the default file. Translate title value and erase the ?French? items and its link.
Also copy the mainLayout definition from the default file. Translate title, and change footer value to ?/fr/common/footer.jsp?. Also write such file.
Your definition description file should looks like :
Do the same for others language.
You can now try your i18n pages. Point your browser on the index.jsp page, and select another language. Watch the window title, and the footer.
In the menu, select a page extending the mainLayout definition, like ?Extended Definition?. Check the footer : it is the one defined by mainLayout definition in the localized description file because shown definition extends mainLayout.
The same mechanism than i18n can be used for channels (wml, different browser support, ?). Each channel components are written under a different directory.
Work in progress. Example available in comps-channel.war.
The idea for channel system is to write another definition factory that will choose the component to insert according to the provided definition name, and a channel key extracted from wherever you want (value from session, , ?). Actually, factory implementation is clearly separated from the rest. If you are interested, you can write your own factory. It needs to implement ComponentDefinitionsFactory.java (1 method). You can let ComponentActionServlet create your factory by setting the servlet init parameter definitions-factory-class to the name of your factory. You can also define init parameters for your factory. They will be passed in a Map. Again, check example in comps-channel.war.
Copyright © 2000-2002, Apache Software Foundation
and Cedric Dumoulin