Invoking Templates by Name

Up to this point, we’ve always used XSLT’s <xsl:apply-templates> element to invoke other templates. You can think of this as a limited form of polymorphism; a single instruction is invoked a number of times, and the XSLT processor uses each node in the node-set to determine which <xsl:template> to invoke. Most of the time, this is what we want. However, sometimes we want to invoke a particular template. XSLT allows us to do this with the <xsl:call-template> element.

How It Works

To invoke a template by name, two things have to happen:

  • The template you want to invoke has to have a name.

  • You use the <xsl:call-template> element to invoke the named template.

Here’s how to do this. Say we have a template named createMasthead that creates the masthead of a web page. Whenever we create an HTML page for our web site, we want to invoke the createMasthead template to create the masthead. Here’s what our stylesheet would look like:

<xsl:template name="createMasthead">
  <!-- interesting stuff that generates the masthead goes here -->
</xsl:template>
...
<xsl:template match="/">
  <html>
    <head>
      <title><xsl:value-of select="title"/></title>
    </head>
    <body>
      <xsl:call-template name="createMasthead"/>
...

Named templates are extremely useful for defining commonly used markup. For example, say you’re using an XSLT stylesheet to create web pages with a particular look and feel. You can write named templates that create the header, footer, navigation areas, or other items that define how your web page will look. Every time you need to create a web page, simply use <xsl:call-template> to invoke those templates and create the look and feel you want.

Even better, if you put those named templates in a separate stylesheet and import the stylesheet (with either <xsl:import> or <xsl:include>), you can create a set of stylesheets that generate the look and feel of the web site you want. If you decide to redesign your web site, redesign the stylesheets that define the common graphical and layout elements. Change those stylesheets, regenerate your web site, and voila! You will see an instantly updated web site. (See Chapter 9 for an example.)

Templates à la Mode

The XSLT <xsl:template> element has a mode attribute that lets you process the same set of nodes several times. For example, we might want to process <h1> elements one way when we generate a table of contents, and another way when we process the document as a whole. We could use the mode attribute to define different templates for different purposes:

<xsl:template match="h1" mode="build-toc">
  <!-- Template to process the <h1> element for table of contents -->
</xsl:template>

<xsl:template match="h1" mode="process-text">
  <!-- Template to process the <h1> element along with the rest   -->
  <!-- of the document                                                  -->
</xsl:template>

We can then start applying templates with the mode attribute:

<xsl:template match="/">
  <html>
    <body>
      <h1>Table of Contents</h1>
      <ul>
        <xsl:apply-templates select="h1" mode="build-toc"/>
      </ul>
      <xsl:apply-templates select="*" mode="process-text"/>
    </body>
  </html>
</xsl:template>

This style of coding makes maintenance much easier; if the table of contents isn’t generated correctly, the templates with mode="build-toc" are the obvious place to start debugging. See Chapter 9 for a more detailed discussion of the mode attribute.

Get XSLT now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.