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).
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.
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.
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.