N341 XSL include and call-template for Modularity

Modified

Basics

Modular programming is a powerful tool that implements functions when there are portions of programs used repeatedly. XSL supports modular implementation of style sheets where a central style sheet file is the combination of several other style sheets.

Our goals for using modular style sheets is three-fold:

  1. implement a standard look-and-feel to pages
  2. create standard style sheet modules that can be reused
  3. allow testing of small modules at the unit-level

XSL include

We have implemented monolithic XSL style sheets successfully so why change?

Consider implementing a standard navigation layout common to many web site pages, Top-Left-Center (TLC). The top and left are defined for navigation and the center is defined for page content. Something similar to that below where the numbers 111111, etc. are top navigation, the letters A, B, ... are left navigation surrounding a middle area for content.

111111 222222 333333
A
B
C
Content of the page goes
here.

The following is the XSL to produce the TLC table.

Top

    <table border="1" cellpadding="0" cellspacing="0">
      <tr>
        <td><a href="syllabus.htm">111111</a></td>
        <td>222222</td>
        <td>333333</td>
      </tr>
    </table>

Left

    <table border="1" cellpadding="0" cellspacing="0">
      <tr>
        <td>A</td>
      </tr>
      <tr>
        <td>B</td>
      </tr>
      <tr>
        <td>C</td>
      </tr>
    </table>

Center

       Content of the page goes here
 In the complete example, note there is no XML data 
so the XSL does nothing here except copy the HTML.
Homepage.htm
<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns="http://www.w3.org/1999/xhtml">
 <xsl:template match="/">

 <table border="1">
  <tr>
    <td></td>
    <td>
    <table border="1" cellpadding="0" cellspacing="0">
      <tr>
        <td><a href="syllabus.htm">111111</a></td>
        <td>222222</td>
        <td>333333</td>
      </tr>
    </table>
    </td>
  </tr>
  <tr>
    <td>
    <table border="1" cellpadding="0" cellspacing="0">
      <tr>
        <td>A</td>
      </tr>
      <tr>
        <td>B</td>
      </tr>
      <tr>
        <td>C</td>
      </tr>
    </table>
    </td>
    <td>
       Content of the page goes here
    </td>
  </tr>
</table>
</xsl:template>
</xsl:stylesheet>
 
111111 222222 333333
A
B
C
Content of the page goes
here.

 

 

A Problem

While this approach works well enough for one page, creating other pages with the same navigation requires cloning the navigation elements and editing in by hand the content for each page. This approach propagates the details of a standard navigation scheme to each page, so any changes to the site look-and-feel may require hand editing each page of the Web site!

Before solving the navigation problem consider how to combine separate XSL files. The following defines three files:

  1. Homepage.htm XSL that includes or copies in another file, Content.htm,
  2. Content.htm XSL which produces some page content,
  3. Homepage.xml XML which, when loaded by the browser, references the Homepage.htm file.

Key points:

  1. <xsl:include href="Content.htm" /> - includes the file "Content.htm"
  2. <xsl:call-template name="Content" /> - calls the template "Content"
  3. <xsl:template name="Content" > - names the template "Content" so that it can be called.

You might recognize that the xsl:template name is somewhat similar to defining a function and the xsl:call-template is similar to invoking a function.

Homepage.htm
<xsl:stylesheet version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns="http://www.w3.org/1999/xhtml">

  <xsl:include href="Content.htm" />

  <xsl:template match="/">
     Homepage<br/>
     <xsl:call-template name="Content" />
  </xsl:template>
</xsl:stylesheet>
Content.htm
<xsl:stylesheet version="2.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
   xmlns="http://www.w3.org/1999/xhtml">


   <xsl:template name="Content">
      Content of the page goes here
   </xsl:template>
</xsl:stylesheet>
Homepage.xml

<?xml-stylesheet type="text/xsl"
                           href="Homepage.htm"?>
<top>
</top>

Browser output

Homepage
Content of the page goes here

 

A Solution

Modules support our implementation goals of consistent look-and-feel and reuse more easily than the monolithic solution.

The following is a general TLC user interface solution consisting of four files:

  1. Homepage.htm that includes or copies in other files, Content.htm and Navigation.htm.
  2. Navigation.htm which contains two templates, one for top navigation and one for left navigation.
  3. Content.htm which produces some page content.
  4. Homepage.xml which, when loaded by the browser, references the Homepage.htm file to display results. This is useful for testing the modules without a Web server or ASP program since IE does not process the xsl:include.

Note that it is the xsl:call-template that generates the HTML contained within the named template.

Homepage.htm
<xsl:stylesheet version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns="http://www.w3.org/1999/xhtml">

  <xsl:include href="Navigation.htm" />
  <xsl:include href="Content.htm" />

<xsl:template match="/">
 <table border="1">
  <tr>
    <td></td>
    <td>
     <xsl:call-template name="topNavigation" />
    </td>
  </tr>
  <tr>
    <td>
       <xsl:call-template name="leftNavigation" />
    </td>
    <td>
        <xsl:call-template name="Content" />
    </td>
  </tr>
 </table>
</xsl:template>
</xsl:stylesheet>

Content.htm

<xsl:stylesheet version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns="http://www.w3.org/1999/xhtml">

  <xsl:template name="Content">
     Content of the page goes here.
  </xsl:template>
</xsl:stylesheet>
Navigation.htm
<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns="http://www.w3.org/1999/xhtml">
    
<xsl:template name="topNavigation">
<table border="1">
  <tr>
    <td><a href="syllabus.htm">111111</a></td>
    <td>222222</td>
    <td>333333</td>
  </tr>
</table>
</xsl:template>

<xsl:template name="leftNavigation">
<table border="1">
  <tr>
    <td>A</td>
  </tr>
  <tr>
    <td>B</td>
  </tr>
  <tr>
    <td>C</td>
  </tr>
</table>
</xsl:template>
</xsl:stylesheet>

Homepage.xml

<?xml-stylesheet type="text/xsl"
                           href="homepage.htm"?>
<top>
</top>


Browser output

111111 222222 333333
A
B
C
Content of the page goes
here.

FrontPage and Visual Studio

Note that FrontPage and Visual Studio cannot render in design view files that include other files. All can render the HTML of files that are included (e.g. Content.htm and Navigation.htm.

Exercise  1

  1. Copy and paste the above four files to W:\N341 directory.
  2. Download msxsl.exe to the same directory.
  • Test by loading Homepage.XML into the browser.
  • Test at the command prompt by: msxsl Homepage.xml Homepage.htm
  1. Copy and paste the files below: Employees.XML and Content.htm; deliberately over-writing Content.htm.
    • Test by loading Employees.XML into the browser.
       
  2. Edit Content.htm
    • Add a xsl:template named your first name. The template should contain HTML to display your name at <H1> level.
    • Modify the Homepage.htm file to:
      • call the template so that your name appears immediately above the top navigation bar.
    • Test by loading Employees.XML into the browser.
Employees.XML

<?xml-stylesheet type="text/xsl" 
               href="Homepage.htm"?>
<Employees>
  <Employee> 
	<First>James</First> 
	<Last>Borg</Last> 
	<Salary>38000</Salary>
  </Employee>  
  <Employee>    
	<First>Joyce</First>   
	<Last>English</Last>
	<Salary>45000</Salary>
  </Employee>
  <Employee>    
	<First>Fred</First>   
	<Last>Flintstone</Last>
	<Salary>25000</Salary>
  </Employee>
</Employees>
Content.htm
<xsl:stylesheet version="2.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns="http://www.w3.org/1999/xhtml">

 <xsl:template name="Content">
   <table border="1">
     <tr>
	<td>First</td>
	<td>Last</td>
     </tr>
     <xsl:for-each select="Employees/Employee">
	<tr>
	   <td><xsl:value-of select="First" /></td>
	   <td><xsl:value-of select="Last" /></td>
	</tr>
     </xsl:for-each>
   </table>
 </xsl:template>

</xsl:stylesheet>

 

Note the function of each file is:

 

Server Side Includes

Another means of combining file is called server side includes, though much less powerful than XSL and XML.

The files end with extensions of stm, shtml, etc. to signal the server to examine the file for include directives before sending to the browser. Server side includes are useful when pages can be assembled from static content located in several files.

The following example would be a file named HW1-4.stm and would display:

Homeworks 1-4

followed by the HTML code from each of the four files named in the #include.

<H3>Homeworks 1-4</H3> 
<!-- #include file="HW1.htm"-->
<!-- #include file="HW2.htm"-->
<!-- #include file="HW3.htm"-->
<!-- #include file="HW4.htm"-->

The following server side file, Homepage.stm, contains includes for the topNavigation.htm and Content.htm files. Note that these are the much the same files used for the XSL include. There are several key differences:

  1. XSL allows calling named templates to select those needed from among several in file.
  2. Server side includes merely copy the entire file at the point of inclusion.
  3. Includes requires a server to assemble the included files.
Homepage.stm
<html>
  <body>
   <center>
     <table border="1" cellpadding="0" cellspacing="0">
       <tr>
	<td></td>
	<td>
	  <center>
	    <!-- #include file="topNavigation.htm"-->
	  </center>
	</td>
        </tr>
        <tr>
	<td>
	  <!-- Left Navigation -->
	  <table border="1" cellpadding="0" cellspacing="0">
	     <tr>
		<td>A</td>
	     </tr>
	     <tr>
		<td>B</td>
	     </tr>
	     <tr>
		<td>C</td>
	     </tr>
	  </table>
	</td>
	<td>
	   <!-- #include file="Content.htm" -->
	</td>
         </tr>
       </table>
    </center>
  </body>
</html>
topNavigation.htm
<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns="http://www.w3.org/1999/xhtml">
    
<xsl:template name="topNavigation">
<table border="1" cellpadding="0" cellspacing="0">
  <tr>
    <td><a href="syllabus.htm">111111</a></td>
    <td>222222</td>
    <td>333333</td>
  </tr>
</table>
</xsl:template>
</xsl:stylesheet>

Content.htm

<xsl:stylesheet version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns="http://www.w3.org/1999/xhtml">

  <xsl:template name="Content">
     Content of the page goes here.
  </xsl:template>
</xsl:stylesheet>

Browser output

111111 222222 333333
A
B
C
Content of the page goes
here.

Cascading Style Sheets (CSS)

Cascading Style Sheets (CSS) function within XSL as normal in HTML. This makes sense because the XSL transformations produce the HTML before the CSS are applied. CSS will be discussed in more detail later in the course.