Under Tapestry, a component template is a file that contains the markup for a component.
Component templates are well formed XML documents. That means that every open tag must have a matching close tag, every attribute must be quoted, and so forth.
Note: At runtime, Tapestry parses the documents and only checks for wellformedness. Even when the document has a DTD or schema, there are no validity checks.
For the most part, these templates are standard HTML/XHTML; Tapestry extensions to ordinary markup are provided in the form of a Tapestry namespace:
Bonjour from HelloWorld component.]]>
We'll cover the specific content of templates shortly, but first a few details about connecting a component to its template.
A component template shares the same name as its corresponding class file, but with a ".tml" ending (i.e., Tapestry Markup Language), and is stored in the same package as the corresponding component class.
Under a typical Maven directory structure, the Java class and template files for a component might be:
Likewise, the Java class and template files for a page might be:
The template and the compiled class will be packaged together in the WEB-INF/classes folder of the application WAR.
For pages (but not other components), a second location will be searched: in the web application context. The location is based on the logical name of the page, in the previous example, the template would be
MyPage.tml in the root folder of the web application.
A template on the classpath takes precedence over a file in the web application context.
Allowing pages to store their template in the web context is a feature that may go away at some point. It was included as a way for HTML designers to edit template directly and live preview the template directly, without executing the Tapestry application. This comes with a large number of limitations and leads to a false sense of security that a template that previews correctly will render properly (this is not always the case).
Main Article: Localization
Templates are handled in much the same way as individual files of a component's message catalog: the effective locale is inserted into the name of the file. Thus a German users will see the content generated from
MyPage_de.tml and French users will see content generated from
MyPage_fr.tml. When no specific localization is available, the default location (
MyPage.tml) is used.
It is necessary to enable support for a locale before Tapestry will attempt to localize to that locale. This requires configuration in your application module; if you are using the Tapestry Quickstart archetype, only locale "en" will be enabled by default.
As mentioned above, component templates are well-formed XML documents. This means that if you want to use any Named HTML entities (such as & < > ©), you must use an HTML or XHTML doctype in your template (starting in 5.3, this is more-or-less automatic, see notes below). If you choose to use (X)HTML doctypes in your templates, they will be passed on to the client in the resultant (X)HTML. Note that if your pages are composed of multiple components, each with a template, and each template contains a doctype declaration, only the first doctype encountered by the template parser will be passed on to the client.
It should also be noted that even though XHTML DTDs are valid XML DTDs, HTML DTDs aren't. This means that HTML doctypes cannot be used by XML parsers. Tapestry works around this limitation internally by using XHTML DTDs to parse templates that use HTML DTDs. This internal mapping is possible because XHTML 1.0 is nothing more than "a reformulation of the three HTML 4 document types as applications of XML 1.0," as per the W3C. Don't worry though – the original HTML 4 doctype will still be emitted to the client!
The following are the most common (X)HTML doctypes:
The first one is for HTML5 and is recommended for Tapestry 5.2.5 and later. In versions prior to Tapestry 5.2.5, Tapestry didn't support the HTML5 doctype directly (but see the comments at TAP5-1040 for a work-around).
The Tapestry Namespace
Component templates should include the Tapestry namespace, defining it in the root element of the template.