Tapestry and HTML Production

Tapestry is design to work in a large-scale environment, that typically features two seperate teams: a "creative" team that produces HTML and a "technical" team that produces Tapestry pages, components and Java code.

The division of skills is such that the creative team has virtually no knowledge of Java and a minimal understanding of Tapestry, and the technical team has a limited understanding of HTML (and tend to be color blind).

The typical workflow is that the technical team implements the application, using very minimal HTML ... that is, minimal attention to layout, font size, colors, etc. Just enough to be sure that the functionality of the application is there.

Meanwhile, the creative team is producing HTML pages of what the finished application will look like. These pages are like snapshots of the HTML produced by the running application.

Integration is the process of merging these two views of the application together. Primarily, this involves marking up tags within the HTML page with jwcid attributes, to indicate to Tapestry which portions of the page are dynamic. In this way, the page can be used as a Tapestry HTML template. These changes are designed to be invisible to a WYSIWYG HTML editor.

Tapestry includes a number of additional features to allow the HTML producers to continue working on HTML templates, even after their initial efforts have been integrated with the Java developer's code.

Implicitly removed bodies

In many cases, a component doesn't allow a body, but one may be present in the HTML template. As usual, this is declared in the component's specification. Tapestry considers that body to be a sample value, one which exists to allow the HTML producer to verify the layout of the page using a WYSIWYG editor (rather than having to run the entire application). Tapestry simply edits out the body at runtime.

For example, an HTML producer may create an HTML template that includes a table cell to display the user's name. The producer includes a sample value so that the cell isn't empty (when previewing the HTML layout).

<td><span jwcid="insertName">John Doe</span></td>

The Insert component doesn't allow a body, so Tapestry edits out the content of the <span> tag from the HTML template. The fact that a <span> was used to represent the Insert component in the HTML template is irrelevant to Tapestry; any tag could have been used, Tapestry just cares that the start and end tags balance.

At runtime, Tapestry will combine the HTML template and the Insert component to produce the final HTML:

<td>Frank N. Furter</td>

This editting out isn't limited to simple text; any HTML inside the body is removed. However, none of that content may be dynamic ... the presence of a jwcid attribute will cause a parsing exception.

Explicitly removed bodies

Another feature related to production and integration is the ability to remove sections of the HTML template. Producers often include some optional portions on the page. The canonical example of this is a page that shows a table of results; the HTML producer will usually include extra rows to demonstrate the look and layout of a fully populated page.

The first row will be wrapped by a Foreach and otherwise changed to include dynamic links and output, but what about the other rows?

To handle this case, Tapestry recognizes a special jwcid attribute value: $remove$. Using this special id causes Tapestry to edit out the tag and all of its contents. Thus, each additional <tr> in the table should specify the value $remove$ for attribute jwcid.

  <tr jwcid="foreach">
    <td><span jwcid="insertUserName">John Doe</span></td>
    <td><span jwcid="insertAge">42</span></td>
  <tr jwcid="$remove$">
  	<td>Frank N. Furter</td>
  <tr jwcid="$remove$">
    <td>Bob Doyle</td>

Limiting template content

In a typical Tapestry application, some form of Border component provides a significant portion of every page. This typically includes the outermost <html>, <head> and <body> tags, as well as <table>s used to control layout.

In the static HTML pages from the creative team, this is not directly visible ... they must include all the content normally generated by the Border component in order to see what the HTML page actually looks like.

By default, the entire HTML template is the content for the page. This causes a problem, even after a <span> is added, to represent the Border component ... much of the HTML is duplicated, once from the static HTML, then dynamically from the Border component.

To eliminate this problem, Tapestry has a second special jwcid attribute: $content$. Using this special id causes Tapestry to limit its view of the HTML template to just the content inside the tag. Anything outside the defined content is completely ignored.


Ideally, the HTML pages created by the HTML producers would be used as is as the HTML templates. Changes made for integration, the adding of jwcid attributes and such, would be copied back into the HTML pages.

Given the use of the $remove$ and $content$ jwcid's, this is practical to a point. Once the application starts using a number of re-usable components, there isn't a good way to perform the integration short of cutting and replacing some of the HTML page content to form the HTML template.