CroftSoft / Library / Tutorials

XSLT Templates

David Wallace Croft
Senior Software Architect
CroftSoft Inc

2002-10-21


Abstract

This tutorial describes how to merge your web page templates with your main content using XSLT. It is useful for adding a common header, footer, or sidebar to your web pages without using frames. It is assumed that the reader knows HTML.

Demonstration Files

The Main Content content.html
The Web Template template.html
The Transform Code template.xsl
The Merged Output index.html
All Files Archive xslt.zip

As the original author and copyright holder, I hereby release the files template.html and template.xsl to the Public Domain. You may use and modify these files free of charge and without restriction.

Web Templates

In this demonstration, the template file contains a header and a sidebar with ad banners which we want to make common to all of the pages at our web site. We could manually add the HTML code for the header and sidebar to each of the pages at our web site but that would take a long time for a large site and would have to be repeated each time we wanted to make a change to our common look-and-feel. Another alternative is to embed the main content in an HTML frame but that causes problems with scaling and scrolling. Frames also make it difficult to reference embedded content directly by URL.

The solution advocated in this article is to separate the common look-and-feel of your web site as a template file and then merge it with your content files to create a new file. If you view the source of the input files used in the demonstration, template.html and content.html, you will notice that the merged output, index.html, is the tutorial file you are reading now.

The input files are written in XHTML, which is basically just HTML with a few modifications to make it compatible with XML. If you are not familiar with XML, please see the tutorial "A Brief Introduction to XML" before proceeding.

XSLT in a Nutshell

The XML Stylesheet Transformation Language (XSLT) is used to transform Extensible Markup Language (XML) files from one form to another. XSLT is a declarative language, as opposed to procedural, which operates through recursive matching and substitution. If you examine the demonstration XSLT code template.xsl, you will notice that it has several matching and substitution functions that look something like this:

<xsl:template match="ELEMENT-TO-BE-MATCHED">
  SUBSTITUE-IT-WITH-SOMETHING-ELSE-AND-CONTINUE
</xsl:template>
As an example, consider this code which replaces the placeholder title element <title>TITLE</title> in our template with the actual title from the content file:
<xsl:template match="/html/head/title">
  <title>
    <xsl:apply-templates
      select="$content/html/head/title/node()" />
  </title>
</xsl:template>
Here is another example in which the placeholder template element <content>CONTENT</content> is replaced with the body of the content file:
<xsl:template match="content">
  <xsl:apply-templates
    select="$content/html/body/node()"/>
</xsl:template>

The XSLT "apply-templates select" command means "continue matching from the selected position". This is used to propagate the matching algorithm recursively. Functions without this command do not continue on; they are dead-ends. In the demonstration XSLT code, most of the matching ends with the identity function which simply writes the matched node to the output. This low priority matching rule at the bottom of our XSLT file is only used if another more specific match cannot be made:

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()" />
  </xsl:copy>
</xsl:template>

XHTML/XSLT Separation

You will notice that the XSLT code is very generic and brief. All of the XHTML code that is specific to the look-and-feel of our web site is encoded in the template file. If we ever need to change the look-and-feel, we can change the template file without needing to change the XSLT code.

You will also notice that there is no XSLT code in our XHTML template file. This means it should be feasible for someone who knows XHTML but not XSLT to update the web site. Assuming that they can hand-code XHTML or use a modern web page editor that generates XHTML instead of HTML as output, they can create a template simply by adding a <content /> tag wherever they want the body of the content file to be inserted.

The <content /> tag has no established meaning. It is just a name I chose for the placeholder element to mark the insertion point. I could have used any other name such as <shannon />, the name of my beloved wife, so long as I modified the reference in the XSLT code to match. This is the eXtensibility of XML: the ability to define your own tag names. A web designer who knows XHTML but does not know XSLT can insert tags with unique and unusual names throughout the XHTML template code. An XSLT programmer can then separately write the XSLT code which will search for the unique and unusual tag names in the template file and replace them with data from the content file.

For simplicity, the content file in this demonstration is another XHTML file and the only substitution performed in the XSLT code is <title> for <title> and <body> for <content>. This makes it easy so that the technique described here can be used by a web developer that knows enough XHTML to create the template.html and content.html files; there is no requirement to know XSLT as he can use the template.xsl file unchanged.

XSLT Processors

The next step after udpating the template or content file is to create a merged output file which will be uploaded to the web site. You will need an XSLT processor to execute the transformation instructions. My preferred XSLT processor of choice is Instant SAXON 6.5 by Michael Kay because it does not add whitespace to the XHTML output. Extra whitespace in the resultant XHTML is a problem because it skews the alignment of images that are supposed to be adjacent with no gaps.

Here is the command that I use in my batch/script file template.bat:

\saxon\saxon -o index.html content.html template.xsl
In this example, \saxon\saxon is the path to my command-line XSLT processing utility, -o index.html is a command-line argument which specifies the name of the output file, and content.html template.xsl are command-line arguments which specify the input and transformation command files respectively. You will note that the template.html file is not specified as a command-line argument; it is referenced within the template.xsl file. If you get an error while running this command, it is probably due to a bad tag or character in the XML data file. Remember that, unlike HTML, all XHTML tags must be terminated, e.g., <br /> instead of <br>.

Content Management

I usually arrange my web sites such that each web page is in its own directory or subdirectory. I like using the default filename index.html since you can reference the web page by the directory path instead of the .html extension filename. For example, the URL for this web page is /library/tutorials/xslt/ as opposed to /library/tutorials/xslt.html.

I usually keep my content.html file in the same directory as the index.html file. I usually upload the content.html file to the web server in addition to index.html even though it is not necessary since only the index.html file is actually downloaded and viewed by site visitors. I do this just so I have an extra copy on the server for backup purposes. I also actually use the filename index.xml instead of content.html for my content files in practice; I thought that using the filename content.html would be easier to digest for the purposes of this tutorial.

I place the template.xsl file in a common directory such as /xsl/ since it is shared by most of the web pages on the site. Now that the latest versions of Internet Explorer and Netscape browsers support client-side transformations using XSLT, I plan to insert a line like the following into all of my index.xml content files:

<?xml-stylesheet type="text/xsl" href="/xsl/template.xsl"?>
This instruction tells the browser to download the XSLT stylesheet and merge the template with the content as a client-side operation. For now, however, I continue to pre-transform the content file on my development machine and then upload the merged output file to the server for the benefit of those using older versions of the browsers that do not support XSLT.

Predicted Trends

Now that the major browsers support XSLT, I predict that web page designers will eventually stop using Cascading Style Sheets (CSS) and use XSLT instead. XML-based languages are becoming more comfortable and natural to developers as time goes on. Web page designers will pick up on XSLT once they have learned the basics of XHTML, the replacement for HTML advocated by the W3C. This will be conducive to the evolution of the Semantic Web.

I predict that more web application developers will generate their dynamic content using server-side XSLT. When possible, they will simply send the XML file and let the browser perform the transformation client-side. The XSLT stylesheet they choose will depend on the client device or the native language of the user. Outdated solutions for generating dynamic content on the server such as Java Server Pages (JSP) will fade away as XSLT proves to be more universal across all platforms.

Resources

© 2002 CroftSoft Inc.