Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: scrollbar
Div

Component Templates

{
Wiki Markup
style
float:right; margin: 1em
titleRelated Articles
classaui-label
Content by Label
showLabelsfalse
showSpacefalse
titleRelated Articles
cqllabel in ("component-templates","components","rendering","response") and space = currentSpace()
|background=#eee} {contentbylabel:title=Related Articles|showLabels=false|showSpace=false|space=@self|labels=component-templates,components,rendering,response} {float}

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 XML namespace (xmlns):

Code Block
languagexml
titleA template for a pagexml

<html t:type="layout" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_34.xsd">
    <h1>Bonjour from HelloWorld component.</h1>
</html>
Section

We'll cover the specific content of templates shortly, but first a few details about connecting a component to its template.

...

Info

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 (usually AppModule.java); if you are using the Tapestry Quickstart archetype, only locale "en" will be enabled by default.

...

The following are the most common (X)HTML doctypes:

Code Block
xml
xml

<!DOCTYPE html>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

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 (see TAP5-1040), but there's a partial work-around: just add the following to your page class (or your layout class, if you use one) instead of adding the doctype to your template (.tml) files:

...

.2.5, Tapestry didn't support the HTML5 doctype directly (but see the comments at TAP5-1040 for a work-around).

Since
since5.3
Tapestry 5.3 introduces introduced two significant improvements to template Doctypes. A template without a is parsed as if it had the HTML Doctype ({{}}). In fact, Tapestry creates an in-memory copy of the template that includes the doctype. A template with the HTML Doctype ({{}}) is parsed _as if_ it had the XHTML transitional Doctype. In fact, Tapestry creates an in-memory copy of the template that replaces the line. This applies as well to a template without any Doctype, in which case the XHTML transitional Doctype is inserted at the top. In either case, this means you can use arbitrary HTML entities, such as {{&copy;}} or {{&nbsp;}} without seeing the XML parsing errors that would occur in earlier releases.

...

Component templates should include the Tapestry namespace, defining it in the root element of the template.

Code Block
xml
languagexml

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_34.xsd">
    <head>
        <title>Hello World Page</title>
    </head>
    <body>
        <h1>Hello World</h1>
    </body>
</html>

...

For backwards compatibility, you may continue to use the old namespace URIs: http://tapestry.apache.org/schema/tapestry_5_0_0.xsd or http://tapestry.apache.org/schema/tapestry_5_1_0.xsd. However or  http://tapestry.apache.org/schema/tapestry_5_3.xsd

 

 However, the following elements added, as part of Tapestry 5.1, will not work with the 5_0_0.xsd:

...

The 5_3.xsd fixes some minor bugs in the 5_1_0.xsd, but is functionally equivalent; 5_3.xsd and 5_4.xsd are identical.

Tapestry Elements

Tapestry elements are elements defined using the Tapestry namespace prefix (usually "t:").

...

The following example is a Layout component, which adds basic HTML elements around the page-specific content:

Code Block
xml
languagexml

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
    <head>
        <title>My Tapestry Application</title>
    </head>
    <body>
        <t:body/>
    </body>
</html>

That "<t:body/>" element marks where the containing page's content will be inserted. A page would then use this component as follow:

Code Block
xml
languagexml

<html t:type="layout" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"

  My Page Specific Content

</html>

When the page renders, the page's template and the Layout component's template are merged together:

Code Block
xml
languagexml

<html>
  <head>
    <title>My Tapestry Application</title>
  </head>
  <body>
    My Page Specific Content
  </body>
</html>

...

A <t:container> element contains markup without being considered part of the template. This is useful for components that render several top level tags, for example, a component that renders several columns within a table row:

Code Block
xml
languagexml

<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
  <td>${label}</td>
  <td>${value}</td>
</t:container>

...

A block may be anonymous, or it may have an id (specified with the id attribute). Only blocks with an id may be injected into the component.

Warning

A <t:block> must be in the Tapestry namespace, but the id attribute should not be. This is different from components in the template, where the t:id attribute that defines the component id must be in the Tapestry namespace.

...

Support for the <t:content> element was adding in Tapestry release 5.1. You must use the http://tapestry.apache.org/schema/tapestry_5_1_04.xsd or http://tapestry.apache.org/schema/tapestry_5_3.xsd (or ...5_3 or ...5_1_0.xsd) namespace URI for content to be recognized (otherwise you will see an error about a missing "content" component).

...

Support for the <t:remove> element was added in Tapestry release 5.1. You must use the http://tapestry.apache.org/schema/tapestry_5_1_04.xsd or http://tapestry.apache.org/schema/tapestry_5_3.xsd (or ...5_3 or ...5_1_0.xsd) namespace URI for remove to be recognized (otherwise you will see an error about a missing "remove" component).

...

Another option when rendering output is the use of expansions. Expansions are special strings that may be embedded in template bodies, and borrow some syntax from the Ant build tool.

Code Block
xml
languagexml

  Welcome, ${userId}!

Here, ${userId} is the expansion. In this example, the userId property of the component is extracted, converted to a string, and streamed into the output.

Expansions are allowed inside text, and inside attributes of ordinary elements, and component elements. For example:

Code Block
xml
languagexml

  <img src="${request.contextPath}/images/catalog/product_${productId}.png"/>

...

Note that expansions escape any HTML reserved characters. Specifically, any less-than (<), greater than (>) and ampersand (&) are replaced with &lt;, &ampgtgt; and &amp; respectively. That is usually what you want. However, if your property contains HTML that you want rendered as raw markup, you can use the OutputRaw component instead, like this: <t:OutputRaw value="someContent"/> where someContent is a property containing HTML markup.

...

An embedded component is identified within the template as an element in the t: namespace. Example:

Code Block
xml
languagexml

  You have ${cartItems.size()} items in your cart.
  <t:actionlink t:id="clear">Remove All</t:actionlink>.

...

The open and close tags of a Tapestry component element define the body of the component. It is quite common for additional components to be enclosed in the body of another component:

Code Block
xml
languagexml

<t:form>
  <t:errors/>
  <t:label for="userId"/>
  <t:textfield t:id="userId"/>
  <br/>
  <t:label for="password"/>
  <t:passwordfield t:id="password"/>
  <br/>
  <input type="submit" value="Login"/>
</t:form>

...

Borrowing from the above example, all of the following are equivalent:

Code Block
xml
languagexml

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd" xmlns:a="tapestry-library:ajax">

  <t:ajax.dialog/>

  <span t:type="ajax/dialog"/>

  <a:dialog/>

  . . .

...

Invisible instrumentation involves using namespaced id or type attributes to mark an ordinary (X)HTML element as a component. For example:

Code Block
xml
languagexml

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
<p>
    Merry Christmas:
    <span t:type="Count" end="3">
        Ho!
    </span>
</p>

...

  • via the t:type attribute in the containing template, as in the above example, or
  • within the containing component's Java class using the @Component annotation (and using the t:id attribute on the element in the template). The Component annotation is attached to a field; the type of the component is determined by either the type of the field or the type attribute of the Component annotation.

In most cases, it is merely an aesthetic choice whether to use invisible instrumentation in your templates. However, in a very few cases the behavior of the component is influenced by your choice. For example, when your template includes the Loop component using the invisible instrumentation approach, the original tag (and its informal parameters) will render repeatedly around the body of the component. Thus, for example:

Code Block
xml
languagexml

  <table>
    <tr t:type="loop" source="items" value="item" class="prop:rowClass">
      <td>${item.id}</td>
      <td>${item.name}</td>
      <td>${item.quantity}</td>
    </tr>
  </tabel>

...

You must define a special namespace, usually with the prefix "p":

Code Block
xml
languagexml

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd" xmlns:p="tapestry:parameter">
  . . .

With the "tapestry:parameter" namespace defined, you can pass block using the "p:" prefix and an element name that matches the parameter name:

Code Block
xml
languagexml

<t:if test="loggedIn">
  Hello, ${userName}!
  <p:else>
    Click <a t:type="actionlink" t:id="login">here</a> to log in.
  </p:else>
</t:if>

...

This approach has certain efficiency advantages on both the server (less processing to render the page) and on the client (fewer characters to parse). Tools such as FireBug Firefox Developer Tools and Chrome Developer Tools are useful for allowing you to view the rendered HTML on the client properly.

...

The xml: namespace prefix is built into all XML documents, there is no special configuration (as there is with the Tapestry namespace).

For example:

Code Block
xml
languagexml

  <ul class="navmenu" xml:space="preserve">
    <li t:type="loop" t:source="pages" t:value="var:page">
      <t:pagelink page="var:page">${var:page}</t:pagelink>
    </li>
  </ul>

This will preserve the whitespace between the <ul> and <li> elements, and between the (rendered) <li> elements and the nested <a> elements. For example, the output may look something like:

Code Block
xml
languagexml

  <ul>
    <li>
      <a href="showcart>ShowCart</a>
    </li>
    <li>
      <a href="viewaccount">ViewAccount</a>
    </li>
  </ul>

With normal whitespace compression, you would see the following rendered output:

Code Block
xml
languagexml

  <ul><li><a href="showcart">ShowCart</a></li><li><a href="viewaccount">ViewAccount</li></ul>

...

Marks a point in a template that may be replaced. A unique id (case insensitive) is used in the template and its sub-templates to link extension points to possible overrides.

Code Block
xml
languagexml

  <t:extension-point id="title">
    <h1>${defaultTitle}</h1>
  </t:extension-point>

...

Replaces an extension point from a parent template. <t:replace> may only appear as the immediate child of a root <t:extend> element.

Code Block
xml
languagexml

<t:extend xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
  <t:replace id="title">
    <h1><img src="${context:images/icon.jpg}"/>
    Customer Service</h1>
  </t:replace>
</t:extend>

Scrollbar