| |
ATP (Active Template Pages) is based on XSL stylesheets. The
documentation for the specific tags is in the XSL
stylesheet section. This section describes how ATP works.
ATP lets web designers create active pages
without changing the original text. It uses a separate XSL stylesheet to transform the original document
into a fancy formatted document. Because the active stylesheet is
separate from the passive content, ATP 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.
ATP makes the input file simpler: it can be plain old HTML. It
separates the content (*.atp) 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.
ATP has to match HTML to script fragments using patterns.
ATP works by matching stylesheet patterns to the input HTML,
creating the result HTML following the pattern actions.
ATP analyzing the input HTML into a structured HTML tree
using the XML document object model. For
each node, it finds the best pattern in the XSL and applies the
action. The action prints to the output HTML.
In this example, we're using a blank stylesheet. Even with a blank
stylesheet,
does something useful: it prints out all text,
removing the tags.
hello.atp
<TITLE>Hello, world</TITLE>
<H1>Hi, World!</H1>
<P>The hello, world example is simple.
|
first reads in the ATP file, parsing it like an HTML
file. It adds optional tags, like <html> and </p> and
forces all HTML tags to be lower case.
hello$9342.dom
<html>
<head>
<title>Hello, world</title>
</head>
<body>
<h1>Hi, World!</h1>
<p>The hello, world example is simple.</p>
</body>
</html>
|
Next,
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.
- #document, process children
- <html>, process children
- <head>, process children
- <title>, process children
- "Hello, world", print to output
- <body>, process children
- <h1>, process children
- "Hi, World!", print to output
- <p>, process children
- "The hello, ...", print to output
hello$9342.html
Hello, world
Hi, World!
The hello, world example is simple.
|
's ATP can create standard page layout: common backgrounds,
navigation, headers and footers. This is a common use for any of the
active content creation tools.
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.
Copying elements is easy. The copy template matches all elements
match='*'. When
processes a node whose pattern
matches nothing else, it will execute the copy action. The action
copies the element (xsl:copy-element) and processes the
children (xsl:apply-templates).
<xsl:template match='*'>
<xsl:copy-element>
<xsl:apply-templates/>
</xsl:copy-element>
</xsl:template>
|
For the page template pattern, we use match='/html/body'.
will execute the template in place of the body. We could
have used match='body' and for most ATP pages that would work
fine. But if someone created an internal <body> tag, say in the
middle of a table, that body tag would get the top level decoration.
Probably not what was intended.
<xsl:template match='/html/body'>
<!-- cyan background -->
<body bgcolor='cyan'>
<table width='100%'>
<!-- left margin -->
<tr><td width='240'></td>
<!-- center column -->
<td width='80%'>
<!-- insert body contents -->
<xsl:apply-templates/>
<!-- copyright footer -->
<hr>
Copyright © 1999 Caucho Technology
</td></tr>
</table>
</body>
</xsl:template>
|
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.
<TITLE>Hello, world</TITLE>
<H1>Hi, World!</H1>
<P>The hello, world example is simple.
|
<html>
<head>
<title>Hello, world</title>
</head>
<body bgcolor='cyan'>
<table width='100%'>
<tr><td width='240'></td>
<td width='80%'>
<h1>Hi, World!</h1>
<p>The hello, world example is simple.
</p>
<hr>
Copyright © 1999 Caucho Technology
</td></tr>
</table>
</body>
</html>
|
|
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.
To use the counter tag, just add it to the ATP file.
counter.atp
A counter example:<counter/>
|
|
Here's the addition to the stylesheet file.
default.xsl
<xsl:template match='counter'>
<#= application.attribute.counter++ #>
</xsl:template>
|
The xsl:template tag says we're defining a new tag. The
match='counter' tells
to apply the counter tag
whenever it sees <counter/>.
JavaScript code is between the special expression tags '<#=' and
'#>'.
will insert the value of the expression into the
generated text.
The application object is the same as for
JSP. In fact, stylesheets can use any of the JSP implicit variables.
actually creates a JSP file after processing a ATP file.
It then evaluates the JSP file to create the output HTML. So the
actual processing order is:
- Parse ATP file as HTML
- Find and parse XSL stylesheet
- Applying the stylesheet to the ATP, creating a JSP file
- Execute the JSP file
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.
Scripts use the counter the same as before:
counter.atp
A counter example:
<counter id='test'/>
|
Here's the patterns to do it. The xsl-cache directive
tells
that it can cache the generated JSP file.
can
cache the file because it only depends on the ATP file, not on the
request or on a random number.
default.xsl
<?xsl-cache?>
<xsl:template match='counter'>
<# var id = elt.attribute.id
if (id) { #>
<%=
application.attribute["<#= id #>"]
%>
<# } else { #>
<%= application.attribute.counter++ %>
<# } #>
</xsl:template>
|
The following JSP file is the result.
will
execute the generated JSP file to produce the result. Because
default.xsl was marked as cached, on following requests
will
merely reexecute 'gen438.jsp'.
gen438.jsp
A counter example: <%=
application.attribute["test"]++
%>
|
The previous example can be rewritten by using more clever XQL patterns. One pattern matches counters
with id attributes. Another matches other counters. So the following
stylesheet does the same thing as the previous one.
<?xsl-cache?>
<xsl:template match='counter'>
<%= application.attribute.counter++ %>
</xsl:template>
<xsl:template match='counter[@id]'>
<%= application.attribute["<#=
elt.attribute.id
#>"] %>
</xsl:template>
|
Copyright © 1998-2002 Caucho Technology, Inc. All rights reserved.
Resin® is a registered trademark,
and HardCoretm and Quercustm are trademarks of Caucho Technology, Inc. | |
|