XWeb Tutorial: a simple site describing a person

Welcome to the first XWeb tutorial. We will show you how to create a site that describes a person, maybe a famous author like the example, maybe yourself. The most important features of XWeb will be introduced and some of the basic XSL-commands needed are described shortly -- you should be able to modify and extend the site afterwards and to create your own simple sites.

Since we want to keep it simple we will just use a very simple layout: a page starts always with the same banner, then buttons to access the pages and then the contents itself. These parts are divided by rulers. There will be no navigation sections and we create but don't use images for the banner and the buttons.

The Input Files

Our site will have three pages: a welcome message which is used as homepage, a page with some biographical information and a page with a number of links. All three will use different XML formats -- one of the original XML ideas is to describe everything in an appropriate format and we will try to do this here.

The Homepage

The homepage (content/home.xhtml) is just an ordinary XHTML page. Since it contains only a welcome message it has no structured data and thus using XHTML is very useful -- we get all the layouting capabilities and it is easy to convert this into the HTML output we want. XHTML is the XML version of HTML: add the first line (the XML version and encoding), close all tags including paragraphs (<p>...</p>) and breaks (<br/>) or rulers (<hr/>) and ensure that the attributes use quotations.

The Curriculum Vitae

For the biographical data (content/cv.xml) we use this format:
    <cv title="Title">
        <event date="1.1.1970" title="Whatever">
            Something happened.
        </event>
        ...
    </cv>
It structures the data in an (hopefully) appropriate way and doesn't care about the layout. This is how you should organize your data whenever you can. The [title] attribute of the <cv> element has the same function as the <title> element in the HTML head and will be used as this later.

The Link Page

The links (content/links.xml) are represented very similar to the biographical information:
<links title="Title">
    <link title="Name" url="Location">
        Site description.
    </link>
    ...
</links>
The reason for this similarity is of course that both data sets are very similar.

The Website File

The website file defines how XWeb should generate your site. It has two major parts: the <structure> part and the <layout> part. Both address a completely different aspect of your site: the first defining the structure, the latter defining the look. You can use different layouts with one structure or the same layout with multiple structures by using includes or just by means of copy&paste.

Basics

Our simple website without layout information looks like this:
<website sourceDir="content" targetDir="output" baseURL="file://...">
    <structure>
        <section name="Douglas Adams" type="main">
            <homepage name="Home" sourceFile="home.xhtml" targetFile="index.html" type="xhtml"/>
            <entry name="CV" sourceFile="cv.xml" targetFile="cv.html" type="cv"/>
            <entry name="Links" sourceFile="links.xml" targetFile="links.html" type="links"/>
        </section>
    </structure>
    <layout>
        ...
    </layout>
</website>
The attributes of the <website> element define the place where XWeb should look for the input files (here relative to the position of the website file), where to put the output files (again relative to the website file) and how a webbrowser can find the files. The [baseURL] is used in all generated urls, please change it to match your file system when you are testing. For uploading the files it has to be changed to something like "http://mysite.tld".

Structure

A website structure contains <section>s, which themself can contain a <homepage> and an abitrary number of <entry>s. We only have one section which has a name and a type. We will use both later, the first defines the text on the section banner and the latter will be used to tell XWeb to create this banner.

In this section you can find three pages defined. One is marked as <homepage>, this is often useful to create specific navigations -- we won't use it in this tutorial but since the page is a homepage we use this form here. Again: if you use XML try to think about the semantic of your data and care about the rest later when writing the stylesheets.

The entries all have four attributes which define the name of the entry (used on buttons), the names of the input and output files (which will be placed in the directories defined on the <website> element) and a type. The type is an identifier which will be used in the layout part to define the process that creates the output file from the input file and which images should be created. Just give them names that match your file formats -- here all entries are different formats so we give each of them a different name.

Layout

Now we have to tell XWeb what to do with all these files. This is done in the <layout> section: we define styles for the documents, the sections and the images that should be generated.

Documents

A definition of a document style looks like this:
    <documentStyle type="xhtml">
        <xsl stylesheet="stylesheets/layout.xsl" navigationElement="html"/>
        <image type="normal"/>
    </documentStyle>
This defines how all files of type "xhtml" should be processed, in our example it defines how the homepage should be processed. The <xsl> element tells XWeb to apply an XSL stylesheet -- the most common process (the others are <programCall> to call external programs and <copy> which just copies the file). The [stylesheet] attribute tells XWeb which stylesheet to use, the path is again relative to the position of the website file. The [navigationElement] tells XWeb where to include the navigation information, the value must refer to an existing element in the input and XWeb will add the navigation information below this. Since every XHTML document has an <html> element, we use this for adding the navigation part.

If you don't give the [stylesheet] attribute, XWeb tries to use a stylesheet link in the file and if this fails it will complain. The [navigationElement] is optional but without it you can't create the navigation in the output.

The <image> tells XWeb to create an image of type "normal" for this kind of documents. We will define this later. You can give any number of images you want to have created by repeating the <image> element, e.g. you might want to create buttons with mouseOver effects which are different for the active page and each page should get a different banner -- you'll need five images with different types for each page then.

To avoid generating the navigation elements in the stylesheets for every format we use, we want to reuse the layout.xsl stylesheet for the other formats by just turning our formats into XHTML and then applying the layout stylesheet. This can be done in XWeb, too, by defining an XSL processing chain:

        <documentStyle type="cv">
            <xsl stylesheet="stylesheets/layout.xsl" navigationElement="html">
                <xsl stylesheet="stylesheets/cv2xhtml.xsl"/>
            </xsl>
            <image type="normal"/>
        </documentStyle>
We just nest the stylesheet used to create XHTML into the layout stylesheet information and XWeb will first use this additional stylesheet and apply the outer stylesheet on the result. This way we can easily reuse the navigation aspects in the layout stylesheet and additionally the inner stylesheet can be used for creating plain XHTML, too. Multiple nestings are allowed, but you can use the [navigationElement] only on the outermost stylesheet.

Sections

Since a section is not processed in itself, we don't need any processing information like the <xsl> for the documents. But sometimes you want to create images for a section and we will use this here to create a banner for the site:
        <sectionStyle type="main">
            <image type="section"/>
        </sectionStyle>

Images

Images can be used for creating buttons and banners. We want to use two different images on our site: the buttons and a banner across the top. The definition of a button looks like this:
        <imageStyle width="105" height="24" fileNamePattern="button_%n.png" type="normal">
            <background color="#ffffff"/>
            <text color="#000000">
                    <position hAlign="center" vAlign="center"/>
                    <font name="Times New Roman" bold="true" size="14"/>
                    <shadow color="#cccccc" offsetX="1" offsetY="1"/>
            </text>
        </imageStyle>
This tells XWeb that "normal" images are 105x24 pixels in size and should be stored as files using the naming pattern given as [fileNamePattern]. The "%n" will always be replaced with the name of the page (whitespace and other nasty characters will be replaced with underscores) and the image will be written into the same directory as the page itself. The file extension defines the image format, in this example PNG images will be created (recommended).

The background of the image will be a plain white and XWeb will render black centered text on it with the given font and a light grey shadow with a small offset. The font has to be available on the machine where XWeb is run (change it if you don't use Windows or have a well founded opinion on this specific font *g*) but since the website will use graphical buttons you don't have to care wether your clients have the font installed, so you can use your companies font or the fancy font you found on the net. You can also add images in the background by adding the input file as [imageURL] to the background and setting the [imageMode] to one of "centered", "origin" or "scaled".

The banner definition (type="section") is the same in big with a different [fileNamePattern].

Writing the Stylesheets

Now we have told XWeb to use all these stylesheets we don't have -- let's fix this problem.

Turning our Formats into XHTML

We start with an easy one: the cv2xhtml.xsl:
<?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:template match="cv">
    <html>
        <head>
            <title><xsl:value-of select="@title"/></title>
        </head>
        <body bgcolor="white">
            <table>
                <xsl:apply-templates/>
            </table>
        </body>
    </html>
</xsl:template>

<xsl:template match="event">
    <tr>
        <th><xsl:value-of select="@date"/></th>
        <td>
            <b><xsl:value-of select="@title"/></b>
            <xsl:text> - </xsl:text>
            <xsl:value-of select="."/>
        </td>
    </tr>
</xsl:template>

</xsl:stylesheet>
We won't explain XSL in detail but here are some hints what is going on: the first two lines define this file as XML and as stylesheet. The stylesheet has only two rules: whenever a <cv> element is found (should happen only once) we write the (X)HTML parts that are always needed, using the [title] attribute as title for the page and creating a simple <table> to put all the other information into. The <xsl:apply-templates/> call causes a recursion into all child elements from <cv>, in this case the <event>s.

The rule for an <event> is: create a table row, first cell is a header cell with the [date] attribute of the <event> in it and the second cell gets the [title] in bold font and then the content of the element, i.e. the event description.

Adding the Navigation

Getting the navigation into the output is slightly more complicated. Somehow our stylesheet must create a navigation part which needs the information on all the pages: their URLs, their buttons and so on. This is why we defined the [navigationElement] in out <documentStyle>s: XWeb will put this information into your input files before the stylesheet is applied -- this way the stylesheet can get all information it needs.

To show you how this looks like we use a simple debugging trick. The following stylesheet just returns all input, it makes (in terms of XML) a copy of the input format:

<?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>
This is useful to get files containing XML you otherwise can't see, e.g. the added navigation tree or some intermediate format in an XSL processing chain. We can add this line:
    <file sourceFile="home.xhtml" targetFile="index.xml" type="debug"/>
below the <homepage> in our website file and we get the input for layout.xsl as additional output file index.xml. A <file> is the same as an <entry> or a <homepage> but it won't be used for the navigation, therefore we don't need a name. The debug style looks like this:
    <documentStyle type="debug">
        <xsl stylesheet="stylesheets/debug.xsl" navigationElement="html"/>
    </documentStyle>
Note that it is the same as the "xhtml" style -- just the stylesheet has been changed.

At the end of the new file you can find an addtional element as child of <html>:

<section name="Douglas Adams" src="file://c:/pbecker/projects/xweb/examples/tutorials/simple/output/index.html" type="main">
    <homepage name="Home" sourceFile="home.xhtml" src="file://c:/pbecker/projects/xweb/examples/tutorials/simple/output/index.html" targetFile="index.html" type="xhtml">
        <img alt="Home" border="0" height="24" name="Home" src="file://c:/pbecker/projects/xweb/examples/tutorials/simple/output/button_Home.png" width="105" xwebtype="normal"/>
    </homepage>
    <file active="true" sourceFile="home.xhtml" src="file://c:/pbecker/projects/xweb/examples/tutorials/simple/output/index.xml" targetFile="index.xml" type="debug"/>
    <entry name="CV" sourceFile="cv.xml" src="file://c:/pbecker/projects/xweb/examples/tutorials/simple/output/cv.html" targetFile="cv.html" type="cv">
        <img alt="CV" border="0" height="24" name="CV" src="file://c:/pbecker/projects/xweb/examples/tutorials/simple/output/button_CV.png" width="105" xwebtype="normal"/>
    </entry>
    <entry name="Links" sourceFile="links.xml" src="file://c:/pbecker/projects/xweb/examples/tutorials/simple/output/links.html" targetFile="links.html" type="links">
        <img alt="Links" border="0" height="24" name="Links" src="file://c:/pbecker/projects/xweb/examples/tutorials/simple/output/button_Links.png" width="105" xwebtype="normal"/>
    </entry>
    <img alt="Douglas Adams" border="0" height="60" name="Douglas_Adams" src="file://c:/pbecker/projects/xweb/examples/tutorials/simple/output/banner_Douglas_Adams.png" width="400" xwebtype="section"/>
</section>
If you want to take a look at the file itself you should use some XML viewer (e.g. Internet Explorer) since the formatting is not optimized for human eyes.

This looks quite similar to our <structure> definition and in fact it is a copy of this part of the input which has been extended with some useful information for creating the navigation. First we have [src] attributes on all entries, including <homepage>s and <file>s. If the [baseURL] for the <website> was set correctly they will give a url pointing to the page. One entry has a marker [active] set to "true". This is the page which is currently processed, in this case our debug <file>.

If images where created the information about them is added to the entries as child elements. The syntax for these is close to HTML, all the usual attributes for defining the size, no border and the location are set, additionally the [alt] attribute is set to the name of the page. These nodes can be copied directly into the HTML output to get the images on the pages.

Unfortunately your HTML won't be valid if you do this, since there are two additional attributes HTML doesn't know about: [name] and [xwebtype]. The first gives a name that can be used in JavaScript or for similar purposes. The [alt] attribute is not always suited as you can see by looking at the section banner. The other attribute ([xwebtype]) is very useful if you have multiple images per entry -- you can pick the one you want using this attribute.

If you want valid HTML you can create a new <img> element and add all relevant attributes to it. To keep things simple and short we will copy the nodes here, but the other approach is not much more complicated.

So all information we need is now in our former XHTML format, lets take a look at the stylesheet to create the final output:

<?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="html" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
        indent="yes" doctype-system="http://www.w3.org/TR/html4/loose.dtd"/>

<xsl:template match="html">
        <html>
                <head>
                    <xsl:copy-of select="head/node()"/>
                </head>
                <body bgcolor="white">
                        <div align="center">
                            <xsl:copy-of select="section/img"/>
                        </div>
                        <hr/>
                        <div align="center">
                                <xsl:apply-templates select="section" mode="nav"/>
                        </div>
                        <hr/>
                        <xsl:copy-of select="body/node()"/>
                </body>
        </html>
</xsl:template>

<xsl:template match="homepage|entry" mode="nav">
    <a>
        <xsl:attribute name="href">
            <xsl:value-of select="@src" />
        </xsl:attribute>
        <xsl:copy-of select="img"/>
    </a>
</xsl:template>

</xsl:stylesheet>
Again: two rules are enough (at least in this simple case). Before we declare the rules we ensure that the XSL output will be HTML -- if you drop the <xsl:output> command it will probably work in most browsers, but this way we get (more) valid HTML and it is formatted ok (not perfect, but quite readable).

What happens here? First we will match the document root element ("html") and we will write the basic HTML structure again. Our head will jsut contain everything that is in the <head> of the input file, we force thebody to be white (you can copy the body attributes if you think this is better) and we put the three parts we wanted into the body. You remember? The banner on top, then the navigation, then the page itself, divided by rulers.

This is done here by copying the (first and only) <img> element of the <section> part into the body first (centered), adding a ruler, adding the navigation (see below), a ruler again and then just copying the original body. When processing the navigation part we create a link for each <homepage> or <entry> we find (but not for the <file>) which is just a simple link to the [src] of the page XWeb tells us. The linked object is the <img> created by XWeb -- not much to do for us at all.

All in all a long way up to here but hopefully you will notice that once you have a basic site and the XML formats you need, adding and editing the pages will be really easy. When you add a new file with an existing input format, you just write the new file, add a new <entry> to the website and run XWeb again. A new button will appear without any further work. Or if you want to change the look of your buttons, you just change the <imageStyle> for it and rerun the program -- all buttons will be different. If you don't like the navigation layout -- change layout.xsl and rerun XWeb, you don't have to touch your input files or any other stylesheet for this. Just try to experiment with this sample site or any other sites you find for XWeb, some hints for this follow but otherwise you have learned enough to create your own sites.

Have Fun!

What Else?

Some features where not mentioned above, or only shortly. Here is a list of features not demonstrated in the tutorial site, refer to the other XWeb documentation or examples to learn them:

Exercises

Here are some ideas what you can do to train your skills:
  1. extend the CV and/or links formats to nested lists and write stylesheets for them
  2. add a bibliography with a new format
  3. add images to the buttons (ask your favoured search engine for "free buttons" or create your own)
  4. create valid HTML by removing [name] and [xwebtype] form the <img> tags in the output (create new <img> and copy HTML attributes instead of copying the whole node)
  5. put the navigation to the left side by using an HTML table (probably easier than you would guess)
  6. add sections to the website, marking them in the navigations with dashes
  7. create a two-level navigation where the main navigation is always visible but the second navigation depends on the current section (this one is not easy)