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.
<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.
<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.
<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".
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.
<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.
<sectionStyle type="main"> <image type="section"/> </sectionStyle>
<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].
<?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.
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!