You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by nc...@apache.org on 2003/01/23 22:24:33 UTC

cvs commit: jakarta-tapestry/doc/src/Tutorial2 tutorial-required-pages.xml tutorial-assets.xml tutorial-inspector.xml tutorial-localization.xml tutorial-chapter-intro-examples.xml Tutorial2.xml tutorial-chapter-forms.xml tutorial-chapter-gettingstarted.xml tutorial-pagelinking.xml tutorial-chapter-components.xml tutorial-chapter-builtins.xml

nclayton    2003/01/23 13:24:33

  Modified:    doc/src/Tutorial2 tutorial-chapter-intro-examples.xml
                        Tutorial2.xml tutorial-chapter-forms.xml
                        tutorial-chapter-gettingstarted.xml
                        tutorial-pagelinking.xml
                        tutorial-chapter-components.xml
                        tutorial-chapter-builtins.xml
  Added:       doc/src/Tutorial2 tutorial-required-pages.xml
                        tutorial-assets.xml tutorial-inspector.xml
                        tutorial-localization.xml
  Log:
  Added another three sections: page types, assets, localization (ripped from original tutorial) and inspector (again, ripped from original tutorial)
  
  Revision  Changes    Path
  1.3       +55 -8     jakarta-tapestry/doc/src/Tutorial2/tutorial-chapter-intro-examples.xml
  
  Index: tutorial-chapter-intro-examples.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/doc/src/Tutorial2/tutorial-chapter-intro-examples.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- tutorial-chapter-intro-examples.xml	6 Dec 2002 18:25:39 -0000	1.2
  +++ tutorial-chapter-intro-examples.xml	23 Jan 2003 21:24:33 -0000	1.3
  @@ -3,9 +3,12 @@
     	<para>
     	This section provides a set of examples that show some of the fundamental aspects of
     	Tapestry. It begins with a discussion on Tapestry binding, which is the process by which you 
  -  	as a developer link your objects to the components in the HTML page. Moving on, we 
  +  	as a developer link your objects to the components in the HTML page, or put another way -
  +          it is how you provide to the compoents the values they need (think of methods that
  +          need arguments), as well as a way for the component to change those values.
  +          . Moving on, we
     	create a simple multiple page application using the &PageLink; component, and then show
  -  	how to respond to user actions (typically Submit buttons) via the &ActionLink; component.
  +  	how to respond to user actions (typically &Submit; buttons) via the &ActionLink; component.
     	</para>
     	<para>
     	More advanced examples can be found from <xref linkend="forms"/> onwards.
  @@ -36,6 +39,13 @@
   					<para><emphasis>All OGNL expressions are evaluated in the context of a current object, and a chain 
   					simply uses the result of the previous link in the chain as the current object for the next one. 
   					You can extend a chain as long as you like. (from &OGNL; web site)</emphasis></para></para>
  +                    <figure>
  +                      <title>OGNL binding example</title>
  +                      <programlisting>
  +
  +  &lt;binding&gt; name="value" expression="visit.name"/&gt;
  +                      </programlisting>
  +                    </figure>
   					<para>
   					In Tapestry, the current object that you start with is the object for the page 
   					in question. For the 'hello world' application covered previously, this is the
  @@ -62,7 +72,22 @@
   					<listitem><para>
   					A completely static piece of text, hardcoded into the component specification. As a result, static
   					bindings are not dynamic (being static!) and are read only.
  -					</para></listitem>
  +					</para>
  +                    <figure>
  +                      <title>Static Binding example</title>
  +                      <programlisting>
  +
  +  &lt;static-binding name="value"&gt;Click To Save&lt;/static-binding&gt;
  +                      </programlisting>
  +                    </figure>
  +                    <para>
  +                        The example above would use the text <emphasis>Click to Save</emphasis> as
  +                        the value for the binding. Note that <varname>static</varname> when used to
  +                        refer to a binding type does not mean the same as <varname>static</varname> within
  +                        Java itself. In Tapestry, the meaning is that the value is constant, and will never
  +                        change.
  +                    </para>
  +					</listitem>
   				</varlistentry>
   	
   				<varlistentry>
  @@ -72,9 +97,21 @@
   					or <function>com.mycompany.myclass.MyObject.SOMEVAR</function>. Static bindings must use full qualified
   					object names, except if the property being referenced is within the <function>java.lang</function> package.
   					</para>
  +                        <para>Field bindings important Java code and referenced in pages, which ensures
  +                        that the code and pages are synchronized and that changes occur only in a single place.</para>
   					<para>
  -					Note that field bindings can also be achieved using an OGNL expression and property binding. 
  +					Note that field bindings can also be achieved using an OGNL expression and property binding.
  +                        The reason that field bindings reman is historic. It is likely that they will be removed
  +                        in the 2.4 release, because you can achieve exactly the same thing with an &OGNL;
  +                        binding.
   					</para>
  +                    <figure>
  +                      <title>Field Binding example (set the value to 'true')</title>
  +                      <programlisting>
  +
  +  &lt;field-binding name="value" field-name="Boolean.TRUE"/&gt;
  +                      </programlisting>
  +                    </figure>
   					</listitem>
   				</varlistentry>
   	
  @@ -82,18 +119,28 @@
   					<term>String Binding</term>
   					<listitem><para>
   					Used for localization, the value of this binding should refer to some localized string resource for this page ( 
  -					part of a resource bundle).  The binding is read only.
  -					</para></listitem>
  +					part of a resource bundle).  The binding is read only.  The example below shows a usage of a string=binding
  +                        to provide a value for an &Insert; component. It is assumed that the properties file for the component,
  +                        with at least a line along the lines of <varname>pageTitle=Super Application Title!</varname>.
  +					</para>
  +                    <figure>
  +                      <title>String Binding example </title>
  +                      <programlisting>
  +
  +  &lt;string-binding name="value" key="pageTitle"/&gt;
  +                      </programlisting>
  +                    </figure>
  +					</listitem>
   				</varlistentry>
   			</variablelist>
     		</para>
   			
   			<para>
  -			The next section takes you through the building of slightly a slightly more complex application.
  +			The next section takes you through the building of slightly more complex application.
   			</para>
     	</section>
   
  -		&chapter-three-ex1;
  +		&into-examples-pagelinking;
   		
   		<section id="ex-actions">
   			<title>Simple Actions</title>
  
  
  
  1.11      +13 -68    jakarta-tapestry/doc/src/Tutorial2/Tutorial2.xml
  
  Index: Tutorial2.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/doc/src/Tutorial2/Tutorial2.xml,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- Tutorial2.xml	5 Dec 2002 14:20:38 -0000	1.10
  +++ Tutorial2.xml	23 Jan 2003 21:24:33 -0000	1.11
  @@ -6,10 +6,14 @@
     <!ENTITY chapter-intro SYSTEM "./tutorial-chapter-intro.xml">
     <!ENTITY chapter-gettingstarted SYSTEM "./tutorial-chapter-gettingstarted.xml">
     <!ENTITY chapter-intro-examples SYSTEM "./tutorial-chapter-intro-examples.xml">
  -  <!ENTITY chapter-three-ex1 SYSTEM "./tutorial-pagelinking.xml">
  +  <!ENTITY into-examples-pagelinking SYSTEM "./tutorial-pagelinking.xml">
     <!ENTITY chapter-forms SYSTEM "./tutorial-chapter-forms.xml">
     <!ENTITY chapter-builtins SYSTEM "./tutorial-chapter-builtins.xml">
     <!ENTITY chapter-components SYSTEM "./tutorial-chapter-components.xml">
  +  <!ENTITY chapter-localization SYSTEM "./tutorial-localization.xml">
  +  <!ENTITY chapter-inspector SYSTEM "./tutorial-inspector.xml">
  +  <!ENTITY chapter-required-pages SYSTEM "./tutorial-required-pages.xml">
  +  <!ENTITY chapter-assets SYSTEM "./tutorial-assets.xml">
     %TapestryLinks;
   ]>
   <!-- Conventions:
  @@ -37,51 +41,12 @@
   	&chapter-intro;
   	&chapter-gettingstarted;
   	&chapter-intro-examples;
  -
  -  <chapter id="pages">
  -  	<title>Pages</title>
  -  	<section id="required-pages">
  -  		<title>Required pages in a Tapestry Application</title>
  -  	</section>
  -
  -  	<section id="pages-howto">
  -  		<title>Howto (for various page types)</title>
  -	  	<section id="pages-howto-home">
  -	  		<title>Home</title>
  -	  	</section>
  -	  	<section id="pages-howto-exception">
  -	  		<title>Exception</title>
  -	  	</section>
  -	  	<section id="pages-howto-Inspector">
  -	  		<title>Inspector</title>
  -	  	</section>
  -	  	<section id="pages-howto-stalelink">
  -	  		<title>StaleLink</title>
  -	  	</section>
  -	  	<section id="pages-howto-stalesession">
  -	  		<title>StaleSession</title>
  -	  	</section>
  -  	</section>
  -  </chapter>
  -
  -  &chapter-forms;
  -  &chapter-builtins;
  -
  -  <chapter id="assets">
  -  	<title>Assets</title>
  -  	<section id="assets-what">
  -  		<title>What is an Asset?</title>
  -  	</section>
  -  	<section id="assets-definition">
  -  		<title>Defining and Using Assets</title>
  -  	</section>
  -  </chapter>
  -
  -  <chapter id="localization">
  -  	<title>Localization</title>
  -  </chapter>
  -
  -  &chapter-components;
  +    &chapter-required-pages;
  +    &chapter-forms;
  +    &chapter-builtins;
  +    &chapter-assets;
  +    &chapter-localization;
  +    &chapter-components;
   
     <chapter id="common-tasks">
     	<title>Common Tasks With Tapestry</title>
  @@ -96,27 +61,7 @@
     	</section>
     </chapter>
   
  -  <chapter id="inspector">
  -  	<title>The Component Inspector</title>
  -  	<section id="inspector-navigation">
  -  		<title>Navigation</title>
  -  	</section>
  -  	<section id="inspector-specification">
  -  		<title>Specification</title>
  -  	</section>
  -  	<section id="inspector-template">
  -  		<title>Template</title>
  -  	</section>
  -  	<section id="inspector-properties">
  -  		<title>Properties</title>
  -  	</section>
  -  	<section id="inspector-engine">
  -  		<title>Engine</title>
  -  	</section>
  -  	<section id="inspector-logging">
  -  		<title>Logging</title>
  -  	</section>
  -  </chapter>
  +  &chapter-inspector;
   
     <chapter id="other">
     	<title>Other Considerations</title>
  
  
  
  1.2       +16 -7     jakarta-tapestry/doc/src/Tutorial2/tutorial-chapter-forms.xml
  
  Index: tutorial-chapter-forms.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/doc/src/Tutorial2/tutorial-chapter-forms.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- tutorial-chapter-forms.xml	5 Dec 2002 14:20:38 -0000	1.1
  +++ tutorial-chapter-forms.xml	23 Jan 2003 21:24:33 -0000	1.2
  @@ -28,8 +28,17 @@
   		<figure>
   			<title>The Application Specification</title>
   			<programlisting>
  -			<para><emphasis>INSERT APP SPEC HERE</emphasis></para>
  -			</programlisting>
  +&lt;application name="Forms Tutorial" engine-class="net.sf.tapestry.engine.SimpleEngine"&gt;
  +  &lt;property name="net.sf.tapestry.visit-class"&gt;tutorial.forms.VisitorState&lt;/property&gt;
  +
  +  &lt;page name="Home" specification-path="/tutorial/forms/Home.page"/&gt;
  +  &lt;page name="Success" specification-path="/tutorial/forms/Success.page"/&gt;
  +  &lt;page name="Part1" specification-path="/tutorial/forms/Part1.page"/&gt;
  +  &lt;page name="Part2" specification-path="/tutorial/forms/Part2.page"/&gt;
  +  &lt;page name="Part3" specification-path="/tutorial/forms/Part3.page"/&gt;
  +  &lt;page name="Part4" specification-path="/tutorial/forms/Part4.page"/&gt;
  +&lt;/application&gt;
  +            </programlisting>
   		</figure>
   		
   		<para>The Home page of this application provides some description of what the application is,
  @@ -114,7 +123,7 @@
   			</programlisting>				
   		</figure>
   
  -		<para>An &InputText; component allows you to show simple &lt;input&gt; HTML tags, and have the value bound 
  +		<para>An &TextField; component allows you to show simple &lt;input&gt; HTML tags, and have the value bound 
   		to some property of an object. As we have have already seen, Tapestry is capable of getting the value which 
   		will appear in the form from almost anywhere. In these examples, we will create a Visit object for the application 
   		and bind the form's values to properties on that object. There is however nothing from stopping us using OGNL to 
  @@ -217,7 +226,7 @@
   		input fields. A StringValidator will accept any string type value. In this example, the only real validation
   		will be that a value for every field is that the value is <emphasis>required</emphasis>.  
   		The example will also show some new components such 
  -		as &Delegator;and &Body; which are required in order to support validation. Here is the page specification:</para>
  +		as &Delegator; and &Body; which are required in order to support validation. Here is the page specification:</para>
   
   		<figure>
   			<title>Component Specification, with StringValidator</title>
  @@ -281,7 +290,7 @@
   		all the time, and client side validation is possible if the user agent supports JavaScript.</para>
   	
   		<para>Finally, in order to show an error with validation on the page, we have added an
  -		<varname>errors</varname> component, which simply shows the first error.  The &Delegate; 
  +		<varname>errors</varname> component, which simply shows the first error.  The &Delegator; 
   		component is an easy way to pass the responsibility for rendering to some other object. 
   		As the first error of a validator implements &IRender;, we can use the &Delegator; component to 
   		include its output into the page during the rendering process.  
  @@ -481,7 +490,7 @@
   			
   			<para>
   			Tapestry contains more validators that those shown here, and of course it is not that hard to write
  -			your own.  Also, there are specific components that help in this regard. For example, the &DateField;
  +			your own.  Also, there are specific components that help in this regard. For example, the <varname>DateField</varname>
   			component sets it's own validator, saving you the time in having to declare and attach it yourself.
   			</para>
   		</section>
  @@ -595,7 +604,7 @@
    			</programlisting>
   		</figure>
   
  -		<para>The Java code itself requires no modification, because the &DatePicker; component uses the
  +		<para>The Java code itself requires no modification, because the <varname>DatePicker</varname> component uses the
   		same data type as our previous &ValidField; did.  So, we have made it easier for the user to enter date values, by providing a date picker 
   		component. We can also restrict the possible values for favorite colour, using another built in Tapestry
   		component.
  
  
  
  1.2       +42 -9     jakarta-tapestry/doc/src/Tutorial2/tutorial-chapter-gettingstarted.xml
  
  Index: tutorial-chapter-gettingstarted.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/doc/src/Tutorial2/tutorial-chapter-gettingstarted.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- tutorial-chapter-gettingstarted.xml	5 Dec 2002 14:20:38 -0000	1.1
  +++ tutorial-chapter-gettingstarted.xml	23 Jan 2003 21:24:33 -0000	1.2
  @@ -226,7 +226,7 @@
   Welcome to your first &lt;b&gt;Tapestry Application&lt;/b&gt;
   &lt;p&gt;
   &lt;h1&gt;
  -	&lt;span jwcid="hellotext"/&gt;
  +	&lt;span jwcid="insertSomeText"&gt;This text will be replaced by Tapesty&lt;/span&gt;
   &lt;/h1&gt;
   &lt;/body&gt;
   &lt;/html&gt;
  @@ -237,12 +237,31 @@
   				You will notice that the page is completely normal, apart from the single
   				<emphasis>span </emphasis> tag, which contains an attribute with name
   				<varname>jwcid</varname>.  This is how Tapestry inserts dynamic data
  -				into a page. In this example, Tapestry will completely replace the <emphasis>span </emphasis>
  -				tag, including whatever it wraps when it renders the page.
  +				into a page. In this example, Tapestry will completely replace 
  +				the <emphasis>span </emphasis>
  +				tag, including whatever it wraps when it renders the page -
  +				that is, you will not see the text <emphasis>This text will be
  +				replaced by Tapestry</emphasis>, but rather the value that is
  +				returned by the <varname>getSomeText()</varname> method.
   				<footnote>
   					<para>The tag does not have to be a span tag. Don't worry about it now, it will be covered later.</para>
   				</footnote>
   			</para>
  +			<para>
  +				You may be wondering how Tapestry calls the <varname>getSomeText()</varname>
  +				method. In the specification above, we have used an &OGNL; binding.
  +				This type of binding uses an expression, which can be read like
  +				a JavaBean name. For the above, it means that the expression "someText"
  +				relates to the <varname>getSomeText()</varname> and <varname>setSomeText()</varname>
  +				method respectively. In the case of the &Insert; component, only 
  +				<varname>getSomeText()</varname> is required, so &Insert; will not try to
  +				change the value.   Also note that the example here is very simple, 
  +				and returns a constant String. There is no reason why the value could
  +				not come from a Database, or some other dynamic source. There is no
  +				restriction on what you can do in the method.  Finally, if you do change
  +                the code to return the value a different way, you don't need to change
  +                the specification or HTML template.
  +			</para>
   		</section>
   		<section id="simplest-app-thejavaobject">
   			<title>The Java Object</title>
  @@ -289,14 +308,28 @@
   	"http://tapestry.sf.net/dtd/Tapestry_1_3.dtd"&gt;
   
   &lt;page-specification class="tutorial.hello.Home"&gt;
  -	&lt;component id="hellotext" type="Insert"&gt;
  +	&lt;component id="insertSomeText" type="Insert"&gt;
   		&lt;binding name="value" expression="someText"/&gt;
   	&lt;/component&gt;
   &lt;/page-specification&gt;
   </programlisting>
         </figure>
  +      		<para>
  +      		Note that Tapestry Components are different from JSP tags.
  +      		Specifically, a Tapestry component takes typed values (the
  +      		type is defined in the property binding part of the specification,
  +      		at the top of the specification file).  Secondly, the values of a
  +      		component can be read only, or read/write. In the later case, the 
  +      		component Java code is able to change the value, which causes whatever
  +      		was <emphasis>bound</emphasis> to that property to be changed.
  +      		Lastly, components can be nested. 
  +      		A component may itself be made up of many other 
  +      		components (which themselves might be made up of other components, and so on),
  +      		and can bind the properties of those contained 
  +      		components to properties of itself.
  +      		</para>
   			<para>
  -				Thats it!  You can execute <emphasis>ant run</emphasis> to both
  +				Whew! Thats it!  You can execute <emphasis>ant run</emphasis> to both
   				compile, package and run the Web Application. Go to
   	    <ulink url="http://localhost:8081/learn-tapestry/hello">
   	      <filename>http://localhost:8081/learn-tapestry/hello</filename>
  @@ -387,7 +420,7 @@
   				<varname>jwcid</varname> attributes on elements.
   			</para>
   		   <para>Tapestry doesn't really care what HTML tag you use, as long as you balance
  -			 	the tag correctly.  In fact, it ignores the tag entirely:  the <varname>hellotext</varname>
  +			 	the tag correctly.  In fact, it ignores the tag entirely:  the <varname>insertSomeText</varname>
   				component above could just has easily been identified with a &lt;text&gt; tag,
   				or any other tag for that matter.  Tapestry is only interested in the <emphasis>structure</emphasis>
   				of the HTML template.  The fact that you can use meaningful tags is a convienience;
  @@ -410,14 +443,14 @@
   				components by name. Component names are defined in the page specification.
   			</para>
   			<para>
  -				The component definition includes both name, type and some bound properties.
  +				The component specification includes both name, type and some bound properties.
   				The properties define where the component gets its data from, and what other
   				objects it interacts with.
   				For example, in the 'Hello World' application above, a component
  -				with name <varname>hellotext</varname> was defined to be an &Insert;,
  +				with name <varname>insertSomeText</varname> was defined to be an &Insert;,
   				and was bound to the <varname>someText</varname> property of the
   				page object. In this example, there is no real interaction, as the &Insert;
  -				component does not provide a way for the user to interact with it.
  +				component does not provide any links for the user to click, nor forms to subnmit.
   			</para>
   		</section>
   		<section id="part-logic">
  
  
  
  1.2       +11 -8     jakarta-tapestry/doc/src/Tutorial2/tutorial-pagelinking.xml
  
  Index: tutorial-pagelinking.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/doc/src/Tutorial2/tutorial-pagelinking.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- tutorial-pagelinking.xml	3 Oct 2002 15:50:45 -0000	1.1
  +++ tutorial-pagelinking.xml	23 Jan 2003 21:24:33 -0000	1.2
  @@ -42,10 +42,10 @@
   &lt;/head&gt;
   &lt;body&gt;
   
  -&lt;h1&gt;The firt page&lt;/h1&gt;
  +&lt;h1&gt;The first page&lt;/h1&gt;
   The link shown will take you to page two of this application.
   
  -Click &lt;span jwcid="page2"&gt;here&lt;/span&gt; for the second page!
  +Click &lt;a href="#" jwcid="page2"&gt;here&lt;/a&gt; for the second page!
   
   &lt;/body&gt;
   &lt;/html&gt;
  @@ -77,11 +77,14 @@
   				</figure>
   				</para>
   				<para>
  -				Here we specify that <varname>page2</varname> is a &pageLink; component. The example here
  +				Here we specify that <varname>page2</varname> is a &PageLink; component. The example here
   				supplies the name of the destination page, which is defined in the application specification.
  -				Note that in this case, the PageLink component outputs the content inside the %lt;span&gt;. 
  +				Note that in this case, the &PageLink; component outputs the content inside the %lt;a&gt;.
   				Components that do this are said to <emphasis>render</emphasis> their body sections.
  -				tag.
  +				tag. Using the correct element tag is useful for previewing the template in a browser,
  +                    or some other HTML based editing tool - Tapestry will discard any attribtues that
  +                    are problematic.   Another example (which you have already seen) is the &Insert;
  +                    component, which will discard any content within its body.
   				</para>
   				<para>
   				If a page has no dynamic functionality, it does not require it's own Java object.
  
  
  
  1.3       +1 -1      jakarta-tapestry/doc/src/Tutorial2/tutorial-chapter-components.xml
  
  Index: tutorial-chapter-components.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/doc/src/Tutorial2/tutorial-chapter-components.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- tutorial-chapter-components.xml	24 Nov 2002 14:10:38 -0000	1.2
  +++ tutorial-chapter-components.xml	23 Jan 2003 21:24:33 -0000	1.3
  @@ -21,7 +21,7 @@
   		The sample below is for a tutorial component, called <emphasis>ArrayViewer</emphasis>. 
   		This component can take any Java array, 
   		and render it as an HTML table.  In real applications, the same can be done using alternative components that 
  -		exist in the framework (such as &TableView;). This example exists to show simply how easy it is to build a component.</para>
  +		exist in the framework (such as <varname>TableView</varname>). This example exists to show simply how easy it is to build a component.</para>
   		
   		<para>
   		By the end of this example, you should have learnt the basics of building a component with various properties.
  
  
  
  1.2       +9 -2      jakarta-tapestry/doc/src/Tutorial2/tutorial-chapter-builtins.xml
  
  Index: tutorial-chapter-builtins.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/doc/src/Tutorial2/tutorial-chapter-builtins.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- tutorial-chapter-builtins.xml	5 Dec 2002 14:20:38 -0000	1.1
  +++ tutorial-chapter-builtins.xml	23 Jan 2003 21:24:33 -0000	1.2
  @@ -1,6 +1,13 @@
   <chapter id="built-ins">
   	<title>Using the Built-In Components</title>
  -  	
  +
  +    <para>
  +        This section will provide examples on a couple of basis non-visual built in components,
  +        that are very, very useful.  The &Foreach; component (as you might have guessed from its name)
  +        is used to iterator over a number of element. The other components are used to respond to
  +        various user events, whether via a link or through a form button.
  +    </para>
  +
     	<section id="builtin-foreach">
     		<title>Foreach</title>
   		<para>The &Foreach; component can be used to iterate over some collection of items. 
  @@ -163,7 +170,7 @@
     			<listitem>DirectLink</listitem>
     		</itemizedlist>
     		
  -  		<para>&GeneriLink; is used to construct a simple link to some resource. 
  +  		<para>&GenericLink; is used to construct a simple link to some resource.
     		The resource is not Tapestry specific (i.e: the link can point to anything). GenericLink will render 
     		it's body, and so an HTML template along these lines:</para>
   
  
  
  
  1.1                  jakarta-tapestry/doc/src/Tutorial2/tutorial-required-pages.xml
  
  Index: tutorial-required-pages.xml
  ===================================================================
    <chapter id="pages">
        <title>Pages</title>
        <section id="required-pages">
            <title>Pages in a Tapestry Application</title>
            <para>Tapestry applications have a number of pre-defined pages.
                Of of these you have already seen, is known as the <emphasis>Home</emphasis>
                page - and is the first page of an application.  Tapestry also has
                pages which are shown when some Exception occurs, when a request
                results in a Stale Link <footnote><para>A stale link in Tapestry is defined to
                be the case where the rewind of some component of page <emphasis>within a form</emphasis>
                detects that the component content is now different from the previous
                render.  At the time of writting, this was done by counting the number
                of components during the render and storing this in a hidden field.
                Then, when the user visits the page again, part of the rewind process
                is to count the number of components rendered, and see if it matches
                the value in the hidden field. If not, then a <varname>StaleLinkException</varname>
                is thrown, which will end up showing the <varname>StaleLink</varname> page.
                </para></footnote>
  
                , or Tapestry detects that the session is now stale.
            </para>
  
            <para>
                The following sections will explain how to use the pages in an application,
                and where applicable provide some "best practices" and tips for debugging.
                The tutorial example code provides a page which allows you to force the use
                of these pages, or insert your own. The example is contained in
                <filename>c:\Tapestry-x.x\examples\Tutorial\src\tutorial\pagetypes</filename>
            </para>
            <note>
                <para>
                    Note that all &DirectLink; components within this particular tutorial
                    specify the parameter <varname>stateful</varname> as <varname>false</varname>.
                    This is required because we do not have a defined Visit object, and in any
                    case we don't want any state in this example. If you do not do this, then
                    you will get <varname>StaleSessionException</varname>'s for every request.
                </para>
            </note>
        </section>
  
        <section id="pages-introduction">
            <title>What comes with Tapestry?</title>
            <section id="pages-intro-home">
                <title>Home</title>
                <para>
                    There is not very much to say about the <varname>Home</varname> page, since
                    you must have one for any Tapestry application. However; it is worth nothing
                    that if you know your site or application is going to have a high number
                    of users, that you should ensure that the <varname>Visit</varname> object
                    is not constructed if it is not required. Note that this strategy will only
                    provide benefit if most of the information your users require is available
                    from pages where an HTTP session is not required.
                </para>
            </section>
            <section id="pages-intro-exception">
                <title>Exception</title>
                <para>
                    This page is shown whenever an an application exception occurs that is
                    cannot be handled by Tapestry itself. The default page in Taepstry is
                    useful for developers, but may not quite be what you want you're users so
                    see (hence this tutorial will show you how to define your own page).
                    Part of the default page is shown below:
                </para>
  
                <figure>
                  <title>Example Standard Exception Page</title>
                  <mediaobject>
                     <imageobject>
                        <imagedata format="JPEG" fileref="images/pages-exception.jpg"/>
                     </imageobject>
                  </mediaobject>
                </figure>
  
                <para>
                    The page contains the stack trace, as well as information related to the
                    state of the container and Tapestry at the time the exception occured.
                </para>
            </section>
            <section id="pages-intro-stalelink">
                <title>StaleLink</title>
                <para>
                    <varname>StaleLinkExceptions</varname> are the result of some internal
                    checking within Tapestry, which attempts to ensure that a user does not
                    visit a page later which has changed since the last time they were there.
                    The primary reason is to protect against a non-sensical operation by the
                    user.
                </para>
                <figure>
                  <title>Example Stale Link</title>
                  <mediaobject>
                     <imageobject>
                        <imagedata format="JPEG" fileref="images/pages-stalelink.jpg"/>
                     </imageobject>
                  </mediaobject>
                </figure>
  
            </section>
            <section id="pages-intro-stalesession">
                <title>StaleSession</title>
                <para>
                    This page informs the user that the HTTP session has expired on the server.
                    You might choose to override this an provide a way for the user to re-login
                    (if you application or site supports that) or restart their session in
                    some other manner.   The default page provides a simple explanation of what
                    has happended, and allows the user to restart their session.
                </para>
                <figure>
                  <title>Example Stale Session</title>
                  <mediaobject>
                     <imageobject>
                        <imagedata format="JPEG" fileref="images/pages-stalesession.jpg"/>
                     </imageobject>
                  </mediaobject>
                </figure>
            </section>
        </section>
        <section id="pages-example">
            <title>Changing the exception page</title>
            <para>
                This section will provide an example of changing the exception page.
                The example itself shows a simple error header, some basic user-friendly
                text and the text of the error. The stack trace is not shown on the form. <footnote>
                    This sounds like an excercise for the reader :-)
                </footnote>
            </para>
  
            <para>
                In order to replace the <emphasis>Exception</emphasis> page, you need only
                provide an alternative implementation within the Application specification file.
                An example of this is provded below:
            </para>
            <figure>
                <title>Application Specification, with custom Exception page</title>
                <programlisting>
  &lt;application name="PageTypes Demo" engine-class="tutorial.pagetypes.PageTypesEngine"&gt;
    &lt;page name="Home" specification-path="/tutorial/pagetypes/Home.page"/&gt;
    &lt;page name="Exception" specification-path="/tutorial/pagetypes/NewException.page"/&gt;
  &lt;/application&gt;
                </programlisting>
            </figure>
            <note>
                Note that in the above example, we are providing a new Page for <emphasis>Exception</emphasis>.
                You will note that in the actual code supplied for this tutorial, we use a page
                called <emphasis>NewException</emphasis>. This is because this particular example
                is setup to show both the normal exception, and a new exception page. Normally you
                just need provide a new Exception page.
            </note>
            <para>
                Now we must define this new page. In the case of an exception, tapestry will set
                a binding on the page called <varname>exception</varname>. We provide this on the
                Java object, which you will see below.
                We'll begin with the template. We will create one that is supposed to be "somewhat less
                intimidating" to new users. Of course, given further time, you can make something
                much nicer than this.
            </para>
            <figure>
                <title>Custom Exception Template</title>
                <programlisting>
  &lt;html&gt;
  &lt;head&gt;
      &lt;title&gt;An Error has occurred with the Application&lt;/title&gt;
  &lt;/head&gt;
  
  &lt;body&gt;
  &lt;center&gt;
      &lt;h1&gt;We have 'issues' ... &lt;/h1&gt;
  
      &lt;h2&gt;&lt;font color="red"&gt;&lt;span jwcid="errorMessage"/&gt;&lt;/font&gt;&lt;/h2&gt;
  
      &lt;p&gt;
      We don't think we'll be doing that any time soon, since our system
      appears to have some kind of problem.  We would appreciate it if you
      could &lt;a href="mailto:errors@neverneverland.net"&gt;email us&lt;/a&gt; a copy
      of this page.
      &lt;/p&gt;
  &lt;/center&gt;
  &lt;/body&gt;
  
  &lt;/html&gt;
                </programlisting>
            </figure>
            <para>
                As you can see, it's very basic - but it is enough for this demonstration.
                We need only a very simple page specification (note that the XML header part
                of this specification has not been included, to keep the example smaller):
            </para>
            <figure>
                <title>Custom Exception Page Specification</title>
                <programlisting>
  &lt;page-specification class="tutorial.pagetypes.NewException"&gt;
      &lt;component id="errorMessage" type="InsertText"&gt;
          &lt;binding name="value" expression="exception.message"/&gt;
      &lt;/component&gt;
  &lt;/page-specification&gt;
                </programlisting>
            </figure>
            <para>
                Finally, we require a Java object for the page which holds the binding,
                and provides a way to access the exception:
            </para>
            <figure>
                <title>Custom Exception Page Specification</title>
                <programlisting>
    package tutorial.pagetypes;
  
    import net.sf.tapestry.IBinding;
    import net.sf.tapestry.html.BasePage;
  
    public class NewException extends BasePage {
        public Throwable getException() {
            return exception;
        }
  
        public void setException(Throwable exception) {
            this.exception = exception;
        }
  
        public IBinding getExceptionBinding() {
            return exceptionBinding;
        }
  
        public void setExceptionBinding(IBinding exceptionBinding) {
            this.exceptionBinding = exceptionBinding;
        }
  
        private IBinding exceptionBinding;
        private Throwable exception;
    }
                </programlisting>
            </figure>
            <para>
                That's it!    In the example code, you will see there is an &IEngine; implementation,
                as well as two types of <emphasis>Exception</emphasis> page. The first exception link
                will show you a standard page. The second exception link will show you the page that
                has been defined in this section.  Normally Tapestry will allow you to define only a single
                exception page, which is why we needed to override the engine implementation.  For this
                example, we show the <emphasis>NewException</emphasis> page if the exception being
                thrown is of type <varname>MyException</varname>, and the standard page otherwise.
            </para>
            <para>
                So in summary, we need accessors on the Java object to hold the actual exception instance.
                The rest is entirely up to you - e.g: how you want the exception page to look, etc. Tapestry
                will take care of the rest!  Assuming you have compiled the tutorial code and started a
                server, you should be able to see this example page:
            </para>
            <figure>
              <title>Example Custom Exception Page</title>
              <mediaobject>
                 <imageobject>
                    <imagedata format="JPEG" fileref="images/pages-newexception.jpg"/>
                 </imageobject>
              </mediaobject>
            </figure>
        </section>
    </chapter>
  
  
  
  1.1                  jakarta-tapestry/doc/src/Tutorial2/tutorial-assets.xml
  
  Index: tutorial-assets.xml
  ===================================================================
  <chapter id="assets">
      <title>Assets</title>
      <para>
          This section will introduce you to the way in which Tapestry allows applications to manage
          images, resources, external stylesheets and generally anything else non-Java-code-related that you might want to
          make available within your application.  The section provides examples of how to use a simple
          context asset (you'll learn what this is in just a moment) within a page.
      </para>
      <para>
          In general, the management of assets is often related to the localization of an application. Further information
          about localization is found in
          <xref linkend="localization"/>.
      </para>
      <section id="assets-what">
          <title>What is an Asset?</title>
          <para>
              In Tapestry, external resources (resources not managed by Java code) are called Assets.
              Assets come in three flavors:  external, context and private.
          </para>
          <para>
              <emphasis>External</emphasis> assets live at an arbitrary URL.
              <emphasis>Context</emphasis> assets use a URL within the
              servlet context hosting the Tapestry application, and are deployed
              within the same Web Application Archive (WAR) as the application.
              <emphasis> Private</emphasis> assets come from the Java classpath and are
              resources not normally visible to the web server.
          </para>
          <para>
              Private assets allow for easy deployment because the assets are
              packaged with the HTML templates and Java code of the application,
              inside a Java Archive (JAR) file.
              Private assets support re-usability; a re-usable component may be
              packaged with supporting assets (typically, image files) and used in any
              Tapestry application without change, and without having to locate, extract or
              otherwise fiddle with those assets.
          </para>
          <para>
              The Tapestry framework provides two ways of exposing the assets to the client web browser.
          </para>
          <para>
              First, it provides a service that will access the asset dynamically.
              The URL encodes the application servlet and the resource to download,
              and Tapestry framework code will pump the bytes down to the client web browser.
              This is the default behavior (and is most useful during development).
          </para>
          <para>
              The second method involves copying the asset out to a directory visible
              to the web server, and creating a URL for it in its final location.
              This requires some extra configuration of the application.
              This method also has some implications when deploying new versions of the web application. These
              implications are not covered here (see the developers guide).
          </para>
      </section>
      <section id="assets-definition">
          <title>Defining and Using Assets</title>
          <para>
              This example code will show the use of a context asset.  Assets of this type
              are visible by the browser, through some well defined URL. That is, they
              are effectively public.  The example code for this section can be found in
              <filename>c:\Tapestry-x.x\examples\Tutorial\src\tutorial\assets</filename>.
          </para>
          <para>
              Our goal in this example is to show a simple page, with a heading. The page itself
              is completely useless, since it has no content (apart from the heading) and no
              behavior (you can't do anything).  Buy hey. It's an example, right? Good!
          </para>
          <para>
              As usual, we'll start with the HTML template:
          </para>
          <figure>
              <title>Asset Example - HTML Template</title>
              <programlisting>
  &lt;html&gt;
  &lt;head&gt;
  	&lt;title&gt;Assets Example&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
  
      &lt;table cellpadding="8" valign="middle"&gt;
          &lt;tr&gt;
           &lt;td&gt;
              &lt;a href="http://tapestry.sourceforge.net/"&gt;
                  &lt;img jwcid="poweredbyImage" alt="View Tapestry Home"/&gt;
              &lt;/a&gt;
           &lt;/td&gt;
           &lt;td&gt;
                &lt;font color="navy" size="+2"&gt;&lt;b&gt;&lt;i&gt;Powered by Tapestry&lt;/i&gt;&lt;/b&gt;&lt;/font&gt;
           &lt;/td&gt;
          &lt;/tr&gt;
      &lt;/table&gt;
  
  &lt;/body&gt;
  &lt;/html&gt;
              </programlisting>
          </figure>
  
          <para>
              And now, the page specification:
          </para>
  
          <figure>
              <title>Asset Example - Specification</title>
              <programlisting>
  &lt;page-specification class="net.sf.tapestry.html.BasePage"&gt;
  
    &lt;component id="poweredbyImage" type="Image"&gt;
      &lt;binding name="image" expression="assets.imageAsset"/&gt;
    &lt;/component&gt;
  
    &lt;context-asset name="imageAsset" path="/images/poweredby.jpg"/&gt;
  
  &lt;/page-specification&gt;
              </programlisting>
          </figure>
  
          <para>
              OK - there we have it. There is no Java object, because there is no
              functionality nor property bindings that require one (so we can just
              use the provided <emphasis>net.sf.tapestry.html.BasePage</emphasis>.
          </para>
          <para>
              The &Image; component itself requires only a single parameter, named
              <varname>image</varname>. This should be some kind of asset.  Tapestry allows you
              to define fixed assets in the specification, which is what we have done here.
              The context-asset declaration gives a name to a relative URL. That is,
              the real name will end up being encoded into the HTML
              as <varname>/tutorial/images/poweredby.jpg</varname>. As you can see,
              Tapestry takes care of adding the context specific part to the front
              of the URL, so that you don't have to.
          </para>
          <para>
              If you have compiled the tutorial code and have a server running, you should be able
              to click on the assets example and see a screen similar to this:
          </para>
  
          <figure>
              <title>Context Asset Demonstration</title>
              <mediaobject>
                 <imageobject>
                    <imagedata format="JPEG" fileref="images/assets-example.jpg"/>
                 </imageobject>
              </mediaobject>
          </figure>
      </section>
  </chapter>
  
  
  1.1                  jakarta-tapestry/doc/src/Tutorial2/tutorial-inspector.xml
  
  Index: tutorial-inspector.xml
  ===================================================================
  <chapter id="inspector">
      <title>The Tapestry Inspector</title>
      <para>
  Unlike scripting systems (such as JavaServer Pages and the like), Tapestry applications are gifted
  with a huge amount of information about how they are implemented. The same component
  object model that allows Tapestry to perform so many ordinary functions can be leveraged to
  provide some unusual functionality.
  </para>
      <para>
  Run the Border tutorial from the previous chapter and click on the show inspector button (the
  gear icon in the lower right corner).  A new window will launch, containing the Inspector:
  </para>
      <figure>
        <title>Tapestry Inspector</title>
        <mediaobject>
          <imageobject>
            <imagedata fileref="images/Inspector-Spec.jpg" format="JPEG"/>
          </imageobject>
        </mediaobject>
      </figure>
      <para>
  The Inspector displays live information from the running application; in fact, it is simply another
  part of the application (the drop-down list of pages will include the Inspector page itself).  The
  Inspector is most often used to debug HTML generation by viewing the HTML templates.
  It is also very useful in debugging problems where the wrong data is displayed, since it
  allows the developer to navigate to the particular components and see directly what properties
  are used.
  </para>
      <section id="inspector.navigation">
        <title>Navigation</title>
        <para>
  The inspector allows the user to navigate to any page and any component on a page.
  The drop down list in the upper left corner lists all pages in the application; changing
  the selection immediately updates the Inspector.
  </para>
        <para>Next to the drop down list is the component path; a list of nested component ids, starting
  with "page" to represent the page.  Clicking on any id in the path changes the information displayed
  below.
  </para>
        <para>
  Underneath the component navigation tools are a set of tab buttons for the different
  inspector views.
  </para>
      </section>
      <section id="inspector.specification">
        <title>Specification View</title>
        <figure>
          <title>Specification View</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="images/Inspector-Spec.jpg" format="JPEG"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>
  The specification view shows several sets of information about the selected component.
  </para>
        <para>
  First shown are basic properties, such as the specification path and Java class.
  </para>
        <para>
  Each formal parameter is displayed.  Unbound parameters will show no value in
  the Binding column.
  </para>
        <para>
  Beneath formal parameters are informal parameters (the <classname>Border</classname>
  component has none, so there is nothing to see).  Informal parameters are
  usually mapped directly to HTML attributes.  They are most often used with
  components that generate a single HTML tag, such as the &ActionLink;,
  &DirectLink; or &TextField; components.
  </para>
        <para>
  If the component contains assets, they are shown next.
  </para>
        <para>
  Any helper beans for the component are displayed last.
  </para>
        <para>
  On the right side is a list of each embedded component and its type.  Clicking
  the component id will navigate to the selected component.
  </para>
      </section>
      <section id="inspector.template">
        <title>Template View</title>
        <figure>
          <title>Template View</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="images/Inspector-Template.jpg" format="JPEG"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>
  The template view shows the HTML template for the component.  It shows dynamic tags in bold,
  and makes the component id a clickable link (which navigates to the component, but maintains
  the Template View).  This allows the developer to quickly drill down through the components.
  </para>
      </section>
      <section id="inspector.properties">
        <title>Properties View</title>
        <figure>
          <title>Properties View</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="images/Inspector-Properties.jpg" format="JPEG"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>
  The properties view shows persistant properties stored by the page (or any components on
  the page).  Most pages do not store any persistent state (it is more often stored
  in the application's visit object).
  </para>
      </section>
      <section id="inspector.engine">
        <title>Engine View</title>
        <figure>
          <title>Engine View</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="images/Inspector-Engine.jpg" format="JPEG"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>
  The engine view shows information about the running application engine, as well as some details
  from the application specification.
  </para>
        <para>
  Under Operations are two buttons:  the first restarts the application.  The
  second (when enabled
  	<footnote>
            <para>
  		By default, the reset service (used by the reset button) is disabled.
  		To enable it, set the JVM system property
  		<varname>net.sf.tapestry.enable-reset-service</varname> to true.
  		The service is disabled since it is too tempting a target for a denial
  		of service attack.
  		</para>
          </footnote>) resets the application, which forces a reload of all component specifications
  and HTML templates.  This is useful during development, since it allows for incremental development
  without stopping and restarting the servlet container.
  </para>
        <para>
  Below the operations is a binary dump of the application engine.  This is useful when
  developing to see how large the serialized state is, and perhaps gleam how it might be trimmed.
  </para>
        <para>
  Further below (and not visible in the screen shot above), is a dump of the request context.  This
  is that vast amount of data also displayed when an unexpected exception is thrown.
  </para>
      </section>
      <section id="inspector.logging">
        <title>Logging View</title>
        <figure>
          <title>Logging View (Level Selection)</title>
          <mediaobject>
            <imageobject>
              <imagedata fileref="images/Inspector-Logging.jpg" format="JPEG"/>
            </imageobject>
          </mediaobject>
        </figure>
        <para>
  The Logging view allows dynamic integration with the
  <ulink url="http://jakarta.apache.org/log4j">Log4J</ulink> logging framework.  The top half
  of the page allows the logging level of any category to be
  dynamically set.  This is useful when debugging, since logging output for specific
  classes
  	<footnote>
            <para>
  			By convention, logging categories match the complete class name
  			of the corresponding class.  All Tapestry logging categories
  			conform to this convention.
  		</para>
          </footnote>
  can be individually enabled or disable.
  </para>
        <para>
  The right side is a small second form, allowing new categories to be created.
  This can be useful to make broad changes in logging levels.  For instance, creating
  a category "net.sf.tapestry" would allow the logging level of all Tapestry classes to be
  set in a single place.
  </para>
      </section>
    </chapter>
  
  
  1.1                  jakarta-tapestry/doc/src/Tutorial2/tutorial-localization.xml
  
  Index: tutorial-localization.xml
  ===================================================================
  
  
  <chapter id="localization">
      <title>Localization</title>
      <para>
  One of the most powerful and useful features of the Tapestry framework is the way in which it
  assists with localization of a web application.  This is normally an ugly area in web applications,
  with tremendous amounts of ad-hoc coding necessary.
  </para>
      <para>
  Because Tapestry does such a strong job of seperating the presentation of a component (its
  HTML template) from its control logic (its specification and Java class) it becomes easy for it to
  perform localization automatically.  It's as simple as providing additional localized HTML
  templates for the component, and letting the framework select the proper one.
  </para>
      <para>
  However, the static text of an application, provided by the HTML templates, is not all.
  </para>
      <para>
  Applications also have assets (images, stylesheets and the like) that must also be localized: that
  fancy button labeled "Search" is fine for your English clients, but your
  French clients will require
  a similar button labeled "Recherche".
  </para>
      <para>
  Again, the framework assists, because it can look for localized versions of the assets as it runs.
  </para>
      <para>
  The locale application demostrates this.  It is a very simply application that demonstrates changing
  the locale of a running application
  	<footnote>
          <para>
  		All the translations were performed using
  		<ulink url="http://world.altavista.com/">Babelfish</ulink>, and are probably quite laughable to
  		someone who actually speaks the alternate
  		languages.
  		</para>
        </footnote>
      </para>
      <para>
  A demonstration of localization is built into the Workbench, under the <acronym>L10N</acronym>
        <footnote>
          <para>
  The "10" refers to the number of letters between 'l' and 'n' in the word 'localization'
  </para>
        </footnote> tab.
  The page allows the user to select a new language for the application:
  </para>
      <figure>
        <title>L10N Page (English)</title>
        <mediaobject>
          <imageobject>
            <imagedata fileref="images/localize-home-english.jpg" format="JPEG"/>
          </imageobject>
        </mediaobject>
      </figure>
      <para>
  Selecting "German" from the list and clicking the "Change" button brings you to a new page that
  acknowledges your selection:
  </para>
      <figure>
        <title>Locale Changed (German)</title>
        <mediaobject>
          <imageobject>
            <imagedata fileref="images/localize-changed-german.jpg" format="JPEG"/>
          </imageobject>
        </mediaobject>
      </figure>
      <para>
  Clicking the button (it's labeled "Return" in German) returns you to the L10N page to
  select a new language:
  </para>
      <figure>
        <title>L10N Page (German)</title>
        <mediaobject>
          <imageobject>
            <imagedata fileref="images/localize-home-german.jpg" format="JPEG"/>
          </imageobject>
        </mediaobject>
      </figure>
      <para>
  The neat thing here is that the <classname>L10N</classname> page has been localized into
  German as well; it shows
  equivalent German text, the options in the popup list are in German, and the "Change" button
  has been replaced with a German equivalent.
  </para>
  
  <section id="locale.template">
  	<title>Localization of HTML Templates</title>
  
  <para>
  Localization of HTML templates ia automatic.  When Tapestry reads a template, it looks for a localized version of it.
  In this example, in addition to the English language <filename>Localization.html</filename>, three additional files were created:
  <filename>Localization_de.html</filename>, <filename>Localization_fr.html</filename> and <filename>Localization_it.html</filename>.
  </para>
  
  <para>
  Tapestry tracks the locale for each user using either an HTTP Cookie, or the &HttpSession;.  It makes sure that all templates for all components
  on the page use the best available template; it does a standard search.
  </para>
  
  	</section>
  
  <section id="locale.assets">
  	<title>Localization of Assets</title>
  
  <para>
  In the L10N pages, there are images that are also localized.
  Tapestry has a hand in this as well.  As with HTML templates, Tapestry
  searches for matches based on the user's locale.
  
  </para>
  
  <para>
  Both context assets (assets that are part of the WAR) and private assets (assets that are stored in Java frameworks) can be localized.  This is demonstrated
  on the L10N page:  the "Change" button is a private asset; the "Back" button is a context asset.
  
  </para>
  
  </section>
  
    <section id="locale.other-options">
        <title>Other Options for Localization</title>
        <para>
  In some cases, different localizations of the a component will be very similar, perhaps having only
  one or two small snippets of text that is different.
  In those cases, it may be easier on the developer to not localize the HTML template, but to
  replace the variant text with an
  &Insert; component.
  </para>
        <para>
  The page can read a localized strings file (a <filename>.properties</filename> file) to get
  appropriate localized text.  This
  saves the bother of maintaining multiple HTML templates.  This is the same approach taken
  by the Apache Struts framework.
  </para>
        <para>
  All components on a page share the single locale for the page, but each performs its own search
  for its HTML template.  This means that some components may not have to be localized, if they
  never contain any static HTML text.  This is sometimes the case for reusable components, even
  navigational borders.
  </para>
      </section>
  </chapter>