caucho
 Using XSL for common formatting boxes


Many common formatting idioms, like boxes, are repeated throughout a web site. Each box has the same design throughout the site, but its HTML implementation is a verbose combination of tables. Changing the site design involves changing each of the tables. The many identical changes make the site more brittle and less changeable.

An XSL box formatting library lets a site create a consistent look, keeping the design stored in one place. Instead of cutting and pasting table definitions, the page refers to the name of a box, like border-box, and lets XSL do the formatting.

A Screen Box

The first element is a simple screen box. Like the screen of the following example, the screen-box creates a rectangle with a solid background. In the following, the bgcolor and title are optional.

Using screen-box
<screen-box bgcolor="#ff8080">
<title>A Sample Box</title>
This is a little bit of data.
</screen-box>

The example, with title looks as follows, basically the same as the example above.

A Sample Box
This is a little bit of data.

The XSL template gives additional flexibility to the tag. That complicates the template slightly. Any attribute in the screen-box will be automatically added to the table. In addition, the <title> tag is optional adding an extra $if.

screen-box XSL
screen-box <<
  <table cellpadding="3" cellspacing="0"
         border="0" width="100%" bgcolor="silver">

    $for-each(@*) << $copy(); >>

    $if (title) <<
      <caption>$apply-templates(title/node());</caption>
    >>

    <tr><td>
      $apply-templates(node()[name(.)!="title"]);
    </td></tr>
  </table>
>>

A Border Box

The second box is just a different style. It has a colored border and a colored in title bar. The HTML is entirely different, but by using the stylesheet, the XML source can be identical. The XML specifies the formatting and the stylesheet carries it out.

Using border-box
<border-box bgcolor="#ff8080">
<title>A Sample Box</title>
This is a little bit of data.
</border-box>

With a similar XML source, the result is entirely different.

A Sample Box
This is a little bit of data.

To provide the full flexibility of the screen-box, the attributes must be split between the generated tables. It's straightforward, if a bit verbose. The border attribute, for example, needs to be converted to a cellpadding of an inner table.

border-box stylesheet
border-box <<
  <table border=0 cellspacing=0 cellpadding=1
         width='100%' bgcolor="silver">
    $if (@border) <<
      $attribute(cellpadding) << $(@border) >>
    >>

    $for-each(@*[name(.)!="border" and name(.)!="cellpadding"]) <<
      $copy();
    >>

  $if (title) <<
    <tr><td>
      <table border=0 cellpadding=0 cellspacing=0 width='100%'>
      <tr><td><font size="+1"> <b>
            $apply-templates(title/node());
      </b></font></td></tr>
      </table>
    </td></tr>
  >>

  <tr><td>
    <table border=0 cellpadding=3 cellspacing=0 width='100%'>

      $for-each(@cellpadding) << $copy(); >>

    <tr><td bgcolor="white">
      $apply-templates(node()[name(.)!="title"]);
    </td></tr>
    </table>
  </td></tr>
  </table>
>>

An Example Box

The example box shows nothing new technically, but does show an important organizational difference. screen-box and border-box are formatting tags. An example tag is meaningful to the source XML. The advantage of an example tag is that the formatting can be changed meaningfully for an entire site.

It makes sense to change the formatting of an example from a screen-box to a border-box. It doesn't make sense to change the formatting of the border-box to a screen-box. By using more meaningful tags like example, the site can more easily change to formatting to make it more readable.

Using example
<example>
<title>An Example Box</title>
This is a little bit of example data.
</example>
An Example Box
This is a little bit of example data.

Because the example tag has a definite style, the XSL implementation is simpler than the more general border-box that achieves a similar result.

example stylesheet
example <<
  <table border=0 cellspacing=0 cellpadding=1
         width='100%' bgcolor="#ff8080">
  $if (title) <<
    <tr><td>
      <table border=0 cellpadding=0 cellspacing=0 width='100%'>
      <tr><td><font size="+1"> <b>
            $apply-templates(title/node());
      </b></font></td></tr>
      </table>
    </td></tr>
  >>

  <tr><td>
    <table border=0 cellpadding=3 cellspacing=0 width='100%'>

    <tr><td bgcolor="white">
      $apply-templates(node()[name(.)!="title"]);
    </td></tr>
    </table>
  </td></tr>
  </table>
>>

Copyright © 1998-2002 Caucho Technology, Inc. All rights reserved.
Resin® is a registered trademark, and HardCoretm and Quercustm are trademarks of Caucho Technology, Inc.