XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

Component-Based Page Layouts

February 16, 2000


Resources

James Clark's XT XSLT processor
W3C XSLT Recommendation
W3C XLink specification
W3C XHTML 1.0
W3C Namespaces in XML
W3C's SVG Page

Printed newspapers and magazines are created by a team of content authors, editors, and people whose task it is to aggregate and lay out the content in a coherent and pleasing way.

Let's take the example of a magazine and simplify the workflow a little: authors deliver their content to the editor, who (obviously) edits the content. Subsequently, the content is ready to be positioned in the magazine's page layout. Content is not necessarily limited to text, but may also contain illustrations.

An electronic magazine is also an assemblage of text and image content. Moreover, other kinds of components can be included in a web page, including interactive components like applets, plug-ins, or ActiveX objects. Each component may be produced by a different author.

Let's examine how the assembly of such a site can be done with XHTML. XHTML is part of the next generation of publishing languages for the Web. One main advantage of XHTML is that, in contrast to its predecessor HTML, it can be extended with new elements. This article will demonstrate how, by using new elements and XSLT transformation sheets, you can aggregate content coming from external documents into a single XHTML document.

A Basic XHTML Page Layout

Well-structured web sites have an integrated look and feel. If each individual component author created his or her own vision of the site, it would end up very disorganized and visually confusing.

Looking at the structure of most web sites, we notice that they have a similar visual layout. At the top, a header; at the bottom, a footer; at the left, a navigation area or table of contents; and, at the right, the content. This visual structure is illustrated in figure 1.

Basic XHTML page layout
Figure 1: Typical site layout

In the XHTML world, one way to create a layout like that shown in Figure 1 is to use either a frameset or a table. (In order to support the widest range of browsers, we must use both in the same page.) In XHTML, as well as in HTML 4.01, the <frameset> element should be used in tandem with the <noframe> element. The <noframe> element's content is used by browsers that do not support frames. This element can contain a table, and the table's cells can contain the components of the frameset. "But wait a minute," you ask, "How can I still use the components as separate documents in the <noframe> section?" Indeed, a good question.

Expand XHTML with a component Element

We know it is possible to include components as separate documents in a <frameset> element, but not in the <noframe> section. Let's then include in the <noframe> section elements of our own invention named <xscript:component>, and use a bit of XSLT magic to obtain the same effect we get with the <frameset> construct.

The key to XHTML is the letter X, which indicates that it is eXtensible. This means we can add our own elements when we need to. So, to obtain the same layout in the <noframe> section that we get in the <frameset> section, we add to our XHTML a new element that is used to include external document content in cells of the table.

Inheriting Attributes From xlink:simple

The new element, component, is basically a link to a resource. The latest XLink working draft makes it possible for an element to inherit the linking behavior from one of the XLink elements. XLink proposes two kind of links:

  • a one-to-one link
  • a one-to-many link

Since we need our <xstyle:component> element to link to a single resource, we then use the xlink:type="simple" attribute that will transform our element into a link. Several other attributes from the XLink language (like xlink:href, xlink:title, xlink:show) are also useful, so let's integrate them into our element's list of attributes.

Using XSLT as an XLink Interpreter

An important thing to mention here is that we are using the XSLT engine as an XLink interpreter. More specifically, it interprets the link behavior indicated by the xlink:show attribute. When this is set to the "embed" value, the content of the linked resource is included in a table cell. Otherwise an error message is included.

To the xlink attributes we add xstyle attributes to indicate the component's MIME type, its height, its width, and the role it plays in the layout. The xstyle prefix denotes that the attributes are of our invention; we will associate the prefix xstyle with the namespace URI of our choice (in this case http://www.talva.com/2000/xstyle). We do not use the xlink:role attribute because we want to indicate the semantic meaning of the element in a layout context, not in a linkage context. So, our element is a link to an external resource, and its basic properties are described by the following attributes:

xlink:type = "simple"
xlink:href = "URI"
xlink:title = "string"
xlink:show = "embed"
xstyle:type = "MIME type, e.g., image/svg or text/xhtml"
xstyle:height = "numerical value or percentage"
xstyle:width = "numerical value or percentage"
xstyle:role = "header|footer|table-of-content|content"

For instance, the <xstyle:component>, which links our web site template to the header component (in this case, a vector graphics SVG document), looks like this:

<xstyle:component xlink:type="simple"
     xlink:href="header.svg"
     xlink:title="Header Layout Object"
     xlink:show="embed"
     xstyle:type="image/svg"
     xstyle:height="100%"
     xstyle:width="100%"
     xstyle:role="header"/>

Our XSLT transformation sheet must interpret the <xstyle:component> element by first looking for the xlink:show attribute. If this is set to the embed value, then the xstyle:type attribute is used as a switch to select the appropriate behavior.

For instance, in our example XSLT transformation sheet, every component of type "image/svg" is converted into an <embed> element, which can then be displayed in a web browser using the Adobe SVG plug-in (now freely available from Adobe's site).

In cases where the xstyle:type attribute is set to "text/xhtm", the referred document's content is inserted in the table cell.

Examining the XSLT Transformation Sheet

The template performing the XLink interpretation is the one that matches the <xstyle:component> elements:

<xsl:template match="xstyle:component">
   <xsl:choose>
   <!-- we embed the component's content only if 
       the xlink:show attribute is set to 'embed'
   -->
   <xsl:when test="contains(@xlink:show,'embed')">
       <xsl:choose>
           <xsl:when test="contains(@xstyle:type,'image/svg')">
               <embed type="image/svg">
               <xsl:attribute name="src">
                <xsl:value-of select="./@xlink:href"/>
               </xsl:attribute>
               <xsl:attribute name="height">
                   <xsl:value-of select="./@xstyle:height"/>
               </xsl:attribute>
               <xsl:attribute name="width">
                    <xsl:value-of select="./@xstyle:width"/>
               </xsl:attribute>
               </embed>
         </xsl:when>
         <xsl:when test="contains(@xstyle:type,'text/xhtm')">
              <xsl:apply-templates 
                  select="document(@xlink:href)/html:html/html:body/*"/>
         </xsl:when>
         <!-- put here other xstyle formats identified by the
              xstyle:type attribute.
              the attribute's value is the component MIME type.
              For example, if the component is an SVG document, then
              its MIME type is "image/svg".
           -->
      </xsl:choose>
  </xsl:when>
  <xsl:otherwise>
   <!-- We include an error message in the output document
       if the intended behavior is not to embed the content -->
   <p>Error: the &lt;xstyle:component&gt; elements only 
      support the xlink:show attribute set to the value "embed".</p>
  </xsl:otherwise>
 </xsl:choose>
</xsl:template>

When an <xstyle:component> is matched by the template and the xstyle:type is equal to "text/xhtm", then the external document's content is loaded, parsed, and the resultant node set included in the current node set. In our case, the external document content replaces the <xstyle:component> element. Thus, each time an <xstyle:component> element is encountered by the XSLT engine, it is replaced by the external document's content. This magic is accomplished with the document() function.

However, we do not want to include the entire external document's content in each table cell. For example, the XHTML <head> element has no place in a table! We only want to include the content of each external document <body> element. This is accomplished by the following expression.

<xsl:apply-templates
    select="document(@xlink:href)/html:html/html:body/*"/>

(Note that html prefix is associated with the namespace URI for XHTML, http://www.w3.org/1999/xhtml).

Now that we have extracted the right node set, we simply want to copy its content as a replacement for the <xstyle:component> node. The following template does just that:

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

Now, Let's Go to the Lab....

If you are tempted to do some exploration of your own, here is my proposal for this week's lab experiment.But first, to do this experiment, you'll need an XSLT engine that is as compliant as possible with the 1999 W3C XSLT Recommendation. I used James Clark's XT processor.

  1. Place the following documents in the same directory: toc.htm, content.htm, footer.htm, header.svg, template.htm, template.xsl.
  2. Go get the Adobe SVG Viewer; you'll need it to view the SVG drawing (and also for a future lab experiment...).
  3. Process the template.htm document with the template.xsl transformation sheet in order to replace all <xstyle:component> elements with the appropriate content extracted from the external components (i.e., documents).
  4. Try it with your own components.

You can also simply look at the template document, the transformation sheet, and the resultant document. Because the template.htm document is an XHTML document, your browser should immediately interpret and render it. Use the "View Source" option to examine its source.