<title css='default.css'>Java Template Pages</title>

<summarylist/>

<p>JTP (Java Template Pages) is based on XSL stylesheets.  The
documentation for the specific tags is in the <a href='xsl.html'>XSL
stylesheet</a> section.  This section describes how JTP works.

<p>JTP lets web designers create active pages
without changing the original text.  It uses a separate <a
href='xsl.html'>XSL</a> stylesheet to transform the original document
into a fancy formatted document.  Because the active stylesheet is
separate from the passive content, JTP gives designers a tighter
focus.  When worrying about style, designers can concentrate on the
stylesheet.  When concentrating on content, designers can focus on the
text.

<p>JTP makes the input file simpler: it can be plain old HTML.  It
separates the content (*.jtp) from the style (*.xsl).  The tradeoff
is that XSL stylesheets are slightly more complicated than JSP active
pages.  For JSP, scripts execute exactly where they're placed.
JTP has to match HTML to script fragments using patterns.

<p>JTP works by matching stylesheet patterns to the input HTML,
creating the result HTML following the pattern actions.
JTP analyzing the input HTML into a structured HTML tree
using the <a href='xmllib.html'>XML document object model</a>.  For
each node, it finds the best pattern in the XSL and applies the
action.  The action prints to the output HTML.

<section name=blank title='Blank Stylesheet Example'>

In this example, we're using a blank stylesheet.  Even with a blank
stylesheet, <resin/> does something useful: it prints out all text,
removing the tags.

<example title='hello.jtp'>
&lt;TITLE&gt;Hello, world&lt;/TITLE&gt;

&lt;H1&gt;Hi, World!&lt;/H1&gt;

&lt;P&gt;The hello, world example is simple.
</example>

<p><resin/> first reads in the JTP file, parsing it like an HTML
file.  It adds optional tags, like &lt;html&gt; and &lt;/p&gt; and
forces all HTML tags to be lower case.

<example title='hello$9342.dom'>
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Hello, world&lt;/title&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;h1&gt;Hi, World!&lt;/h1&gt;

    &lt;p&gt;The hello, world example is simple.&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
</example>

<p>Next, <resin/> starts its matching process at the top.  Since the stylesheet
is empty, it uses the default rules.  The default rules say: process
an element's children and print a text node's data.

<box class='green'>
<ol>
<li>#document, process children
 <ol>
 <li>&lt;html&gt;, process children
  <ol>
  <li>&lt;head&gt;, process children
   <ol>
   <li>&lt;title&gt;, process children
    <ol>
    <li>"Hello, world", print to output
    </ol>
   </ol>
  <li>&lt;body&gt;, process children
   <ol>
   <li>&lt;h1&gt;, process children
    <ol>
    <li>"Hi, World!", print to output
    </ol>
   <li>&lt;p&gt;, process children
    <ol>
    <li>"The hello, ...", print to output
    </ol>
   </ol>
  </ol>
 </ol>
</ol>
</box>

<example title='hello$9342.html'>
Hello, world

Hi, World!
The hello, world example is simple.
</example>

</section>

<section name=page title='Simple Page Template'>

<resin/>'s JTP can create standard page layout: common backgrounds,
navigation, headers and footers.  This is a common use for any of the
active content creation tools.

<p>This example adds two things to the default stylesheet.  All
elements are copied instead of ignored, and the body of the HTML gets
a background and a margin.

<p>Copying elements is easy.  The copy template matches all elements
<code/match='*'/>.  When <resin/> processes a node whose pattern
matches nothing else, it will execute the copy action.  The action
copies the element (<code/xsl:copy-element/>) and processes the
children (<code/xsl:apply-templates/>).

<example>
&lt;xsl:template match='*'&gt;
  &lt;xsl:copy-element&gt;
    &lt;xsl:apply-templates/&gt;
  &lt;/xsl:copy-element&gt;
&lt;/xsl:template&gt;
</example>

<p>For the page template pattern, we use <code/match='/html/body'/>.
<resin/> will execute the template in place of the body.  We could
have used <code/match='body'/> and for most JTP pages that would work
fine.  But if someone created an internal &lt;body&gt; tag, say in the
middle of a table, that body tag would get the top level decoration.
Probably not what was intended.

<example>
&lt;xsl:template match='/html/body'&gt;
<eg-em>
  &lt;!-- cyan background --&gt;
  &lt;body bgcolor='cyan'&gt;

  &lt;table width='100%'&gt;

  &lt;!-- left margin --&gt;
  &lt;tr&gt;&lt;td width='240'&gt;&lt;/td&gt;

  &lt;!-- center column --&gt;
  &lt;td width='80%'&gt;

  &lt;!-- insert body contents --&gt;
</eg-em>

  &lt;xsl:apply-templates/&gt;

<eg-em>
  &lt;!-- copyright footer --&gt;
  &lt;hr&gt;
  Copyright &amp;copy; 1999 Caucho Technology

  &lt;/td&gt;&lt;/tr&gt;
  &lt;/table&gt;
  &lt;/body&gt;
</eg-em>
&lt;/xsl:template&gt;
</example>

<p>The translation follows the same order as in the blank stylesheet
example.  The body rule is used for the body and the copy-element rule
is used for every other tag.

<example>
<example>
&lt;TITLE&gt;Hello, world&lt;/TITLE&gt;

&lt;H1&gt;Hi, World!&lt;/H1&gt;

&lt;P&gt;The hello, world example is simple.
</example>
<results>
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Hello, world&lt;/title&gt;
  &lt;/head&gt;

  &lt;body bgcolor='cyan'&gt;

  &lt;table width='100%'&gt;
  &lt;tr&gt;&lt;td width='240'&gt;&lt;/td&gt;
  &lt;td width='80%'&gt;

    &lt;h1&gt;Hi, World!&lt;/h1&gt;

   &lt;p&gt;The hello, world example is simple.
   &lt;/p&gt;

  &lt;hr&gt;
  Copyright &amp;copy; 1999 Caucho Technology

  &lt;/td&gt;&lt;/tr&gt;
  &lt;/table&gt;
  &lt;/body&gt;
&lt;/html&gt;
</results>
</example>

</section>


<section name=counter title='Creating a Custom Tag'>

All by itself, the template example is cool.  But here's something
more interesting, creating a custom tag.  In this case, we'll just
create a simple counter.

<p>To use the counter tag, just add it to the JTP file.

<example title='counter.jtp'>
<example>
<eg-em>A counter example:</eg-em>&lt;counter/&gt;
</example>
<results>
A counter example: 2
</results>
</example>

<p>Here's the addition to the stylesheet file.

<example title='default.xsl'>
  &lt;xsl:template match='counter'&gt;
    &lt;#= application.attribute.counter++ #&gt;
  &lt;/xsl:template&gt;
</example>

<p>The <code/xsl:template/> tag says we're defining a new tag.  The
<code/match='counter'/> tells <resin/> to apply the counter tag
whenever it sees <code/&lt;counter/&gt;/>.

<p>JavaScript code is between the special expression tags '&lt;#=' and
'#&gt;'.  <resin/> will insert the value of the expression into the
generated text.

<p>The <a href='jspapp.html'>application</a> object is the same as for
JSP.  In fact, stylesheets can use any of the JSP implicit variables.

</section>

<section name=mixing title="Mixing JTP and JSP">

<p><resin/> actually creates a JSP file after processing a JTP file.
It then evaluates the JSP file to create the output HTML.  So the
actual processing order is:

<ol>
<li>Parse JTP file as HTML
<li>Find and parse XSL stylesheet
<li>Applying the stylesheet to the JTP, creating a JSP file
<li>Execute the JSP file
</ol>

<p>Here's we're going to take advantage of this by creating a named
counter.  If the counter has an 'id' attribute, we'll use it at the
value of the application variable.

<p>Scripts use the counter the same as before:</p>

<example title='counter.jtp'>
<eg-em>A counter example: </eg-em>&lt;counter id='test'/&gt;
</example>

<p>Here's the patterns to do it.  The <code/xsl-cache/> directive
tells <resin/> that it can cache the generated JSP file.  <resin/> can
cache the file because it only depends on the JTP file, not on the
request or on a random number.

<example title='default.xsl'>
&lt;?xsl-cache?&gt;
&lt;xsl:template match='counter'&gt;
  &lt;# var id = elt.attribute.id
     if (id) { #&gt;
       &lt;%= 
         application.attribute["&lt;#= id #&gt;"]
       %&gt;
  &lt;# } else { #&gt;
    &lt;%= application.attribute.counter++ %&gt;
  &lt;# } #&gt;
&lt;/xsl:template&gt;
</example>

<p>The following JSP file is the result.  <resin/> will
execute the generated JSP file to produce the result.  Because
default.xsl was marked as cached, on following requests <resin/> will
merely reexecute 'gen438.jsp'.

<results title='gen438.jsp'>
A counter example: &lt;%= 
  application.attribute["test"]++ 
%&gt;
</results>

</section>

<section name=clever title="Using Clever Patterns">

The previous example can be rewritten by using more clever <a
href='xql.html'>XQL</a> patterns.  One pattern matches counters
with id attributes.  Another matches other counters.  So the following
stylesheet does the same thing as the previous one.

<example>
&lt;?xsl-cache?&gt;

&lt;xsl:template match='counter'&gt;
  &lt;%= application.attribute.counter++ %&gt;
&lt;/xsl:template&gt;

&lt;xsl:template match='counter[@id]'&gt;
  &lt;%= application.attribute["&lt;#= 
    elt.attribute.id
  #&gt;"] %&gt;
&lt;/xsl:template&gt;
</example>

</section>
