Introducing XWeb

Writing XSLT for XWeb layouts

Why the effort?

Although the generic XSLT stylesheet gives you a lot of options to change the look of your site, sometimes this might not be enough to get exactly the design you want. Here are some examples of layouts you can not create with the generic stylesheet:

  • anything with more than two levels of sections
  • main and secondary navigation in different locations
  • framesets (not recommended anyway)

In most cases where the generic stylesheet fails you still can use XWeb to create your website by providing your own, specialized XSLT stylesheet. Two examples that use special stylesheets are the website of the Tockit project, where the main navigation is located at the top and the secondary on the left hand side, and the homepage of Peter where the navigation is two-dimensional: you can always switch between the two available languages without loosing the position.

How does it work?

We assume that you have some basic knowledge about XSLT, i.e. you are able to write simple stylesheets in it. You should be able to turn some simple XHTML files as used e.g. in this manual into nice looking HTML pages. The main question you should have then is: where does the information about the site structure come from and how do I get the links to pages and images?

The answer to this is in some way simple: it is in the input to your stylesheet. The tricky part is that you can not see it directly, it will be added by XWeb if you use the navigationElement attribute on an XSLT process. Let's consider this example:

  <documentStyle type="myXML">
    <xsl stylesheet="layout/myFirst.xsl" navigationElement="nav">
    </xsl>
  </documentStyle>

In this case the following things will happen whenever a document of type "myXML" will be processed:

  1. the document will be opened as XML DOM document in memory
  2. XWeb searches for the first occurance of an element <nav> in the DOM (depth-first search) and adds the navigation information there
  3. an XSLT processor (first TRAX-compliant implementation in the classpath) will be called on the result, using the stylesheet given

Note that the intermediate document which includes the navigation information is never stored as file, it is directly passed into the XSLT processor. Because of this you can not see the input of your stylesheet directly.

There is a rather simple trick to take a look at the input for your stylesheet, which is not only useful for getting an idea about the structure of the input, but also to write and debug your stylesheet. If you would use XWeb all the time you would have to recreate the website every time you tweak your XSLT code, it is far more convinient to test the stylesheet on a single page first. The trick is to write a stylesheet that just writes the input into a file like this:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format">

  <xsl:output method="xml"/>

  <xsl:template match="*">
    <xsl:copy-of select="."/>
  </xsl:template>

</xsl:stylesheet>

Try running this stylesheet on one of your examples and take a look at the output. You should find somewhere in the file created a subtree (below the navigation element) which gives all information you need to create the navigation, including the URLs for the pages and the images.

What information is there?

The information given is based on the <structure> part of the makefile. While processing the site XWeb adds information to the structure and the result of this is added into the documents. A typical element for a page will look like this, only less formatted:

<entry name="Main Page" sourceFile="main.xml" active="true"
       src="http://my.site.com/main.html" targetFile="main.html" type="myXML">
  <img alt="Main Page" border="0" height="24" name="Main_Page"
       src="http://my.site.com/button_Main_Page.png" width="105" xwebtype="normal"/>
  <img alt="Main Page" border="0" height="24" name="Main_Page"
       src="http://my.site.com/button_Main_Page_act.png" width="105" xwebtype="active"/>
</entry>

All information you gave in the makefile will still be there plus:

  • the URL where to find the page in the output (based on the base URL you gave or as local link if a preview is created)
  • a marker for the active page: the attribute active will be set to "true" for the active page (the one that is currently processed), it will not exist for any other page
  • an HTML-like <img> element for each image created. This can be copied directly into the output, although the result will not be valid HTML due to the additional xwebtype attribute. To get valid HTML you have to copy the attributes needed.

Note that the names for the images will be mangled to be safe to use in JavaScript, e.g. for mouse-over effects. They will always be valid JavaScript identifiers, although it is not ensured that two pages can not have the same mangled name, e.g. if two page names differ only in invalid characters they will have the same mangled name. Images for the same page have always the same name, but they are typically treated as one image object anyway. If you want something different you have to extent the names using XSLT.

Sections get similar information: they will have a URL for their main page (i.e. the first page in each section) and if images where created for them they will be given in the same way as for the pages. They are marked as active if the active page is in them, i.e. there will be one active section on each level above the currently processed entry. And of course all sections still contain the <entry>s, <file>s, <section>s and <directory>s from the original makefile structure.

How to use this information

To use this information for creating your own site design you will need only a few basic approaches:

  • wherever you want the navigation to be in your site, add some XSLT code that recurses through the navigation structure using templates with a mode
  • write a named template for adding the buttons -- it makes things easier. Note that you can distinguish the different images by using the xwebtype attribute
  • if you want mouse-over effects, add some code generating JavaScript for preloading the images and add the appropriate attributes to the code for creating the buttons

There are examples how to write XSLT and XPath expressions available as XSLT reference and XPath reference. Take a look at the examples coming with the XWeb distribution for more ideas and once you feel confident enough, you can take a look at the generic stylesheet. Note that the generic stylesheet is not a good point to start with: it is pretty complicated due to the available options and parameters. It will be a good example once you got hold of the basic approaches, but it is not suited for beginners unless they like jumping into cold water ;-)