HTML Templates

Nearly all Tapestry components combine static HTML [2] from a template with additional dynamic content (some few components are just dynamic content). Often, a Tapestry component embeds other Tapestry components. These inner components are referenced in the containing component's template.

One of the features of Tapestry is invisible instrumentation. In most web application frameworks, converting a static HTML page into a usable template is a destructive process: the addition of new tags, directives or even Java code to the template means that it will no longer preview properly in a WYSIWYG editor.

Tapestry templates are instrumented using a new HTML attribute, jwcid, to any existing element. Elements with such attributes are recognized by Tapestry as being dynamic, and driven by a Tapestry component, but a WYSIWYG editor will simply ignore them. Once a template is instrumented, it may be worked on by both the HTML producer and the Java developer.

Identifying a Tapestry component within an HTML template is accomplished by adding a jwcid attribute to a tag.

<any jwcid="component id" ... >  body  </any>

or

<any jwcid="component id" ... />

Most often, the HTML element chosen is <span>, though (in fact) Tapestry completely ignores the element chosen by the developer, except to make sure the open and close tags balance.

The parser used by Tapestry is relatively forgiving about case and white space. Also, the component id (and any other attributes) can be enclosed in double quotes (as above), single quotes, or be left unquoted.

You are free to specify additional attributes. These attributes will become informal parameters for the Tapestry component.

The start and end tags for Tapestry components must balance properly. This includes cases where the end tag is normally ommitted, such as <input> elements. Either a closing tag must be supplied, or the XML-style syntax for an empty element must be used (that is, a slash just before the end of the tag).

Localizing sections of a template

Tapestry includes an additional template feature to assist with localization of a web application. By specifying a <span> element with a special attribute, key, Tapestry will replace the entire <span> tag with a localized string for the component.

This construct takes one of two forms:

<span key="key" ... > ... </span>

or

<span key="key" ... />

If only the key attribute is specified, then the <span> is simply replaced with the localized string. However, if any additional attributes are specified for the <span> tag beyond key, then the <span> tag will be part of the rendered HTML, with the specified attributes.

The upshot of this is that sections of the HTML template can be invisibly localized simply by wrapping the text to be replaced inside a <span> tag. The wrapped text exists, once more, as sample text to be displayed in a WYSIWYG editor.

Components with Bodies

In Tapestry, individual components may have their own HTML templates. This is a very powerful concept ... it allows powerful and useful components to be created with very little code. By contrast, accomplishing the same using JSP tags requires either that all the HTML be output from the JSP tag directly, or that the JSP tag use some additional framework, such as Velocity, to enable the use of a template. In either case the JSP tag author will need to divide the code or template into two pieces (before the body and after the body). Tapestry allows components to simply have a single template, with a marker for where the body is placed.

During the rendering of a page, Tapestry knits together the templates of the page and all the nested components to create the HTML response sent back to the client web browser.

Container content 1

<span jwcid="component"> 2

  Body content 3
  
</span>

More container content 4
1

This portion of the container content is rendered first.

2

The component is then rendered. It will render, possibly using its own template.

3

The component controls if, when and how often the body content from its container is rendered.

Body content can be a mix of static HTML and additional components. These components are wrapped by the component, but are embedded in the component's container.

4

After the component finishes rendering, the remaining content from the container is rendered.

The body listed above can be either static HTML or other Tapestry components or both. Elements in the body of a component are wrapped by the containing component. The containing component controls the rendering of the elements it wraps in its body. For example, the Conditional component may decide not to render its body and the Foreach component may render its body multiple times.

Not all Tapestry components should have a body. For example, the TextField component creates an <input type=text> form element and it makes no sense for it to contain anything else. Whether a component allows a body (and wrap other elements), or whether it discards it, is defined in the component's specification.

Tapestry includes a special component, RenderBody, which is used to render the body content from a component's container. It makes it easy to create components that wrap other components.



[2] The current releases of Tapestry is specifically oriented around HTML. Some support for non-HTML languages, such as XML, XHTML or WML is already present and will be expanded in the future.