John's Web Pages


As I have recorded elsewhere, I was an early adopter of web technology (although I will not claim to be an expert in web technology!), and over the years have learnt a bit about how best to put together some web pages. This is not a story for the faint-hearted.

The issue is that these various pages reside on a number of servers (see footer bar), and I did not want the maintenance of various sites to get out of hand. So the idea of mirroring these web pages across a variety of servers seemed like a good idea, avoiding the need for individual site maintenance. Initially this was confined to the School Server, and to my local server; the first to provide the public face, and the second to provide a testing ground before going public. But soon enough this small collection expanded rather, and I found myself making trivial changes many times over, due to the idiosyncracies of each server.

First up there was the question of the locality. Using relative addresses removed many of the localizations, but I also wanted some different behaviours depending upon where a page was being rendered. Making the server name part of the process was what was needed, but how?

Secondly there was the issue of what authoring context to use. Initial pages were written in HTML, but as anyone with experience in writing HTML pages knows, this also gets tedious as the number of sites multiplies. I tried using some macro environments, such as m4, which worked OK, but I wanted something closer to the action. (One of my colleagues still uses this approach, and it works well for him.)

About then XML came on the scene. This seemed to present the best of all worlds - a markup environment that was powerful enough to capture all the nuances, and was sufficiently general to separate content from form. Now all current pages are written in XML (some legacy pages are still in HTML), and translated on the fly by XSLT scripts.

How It's Done

Page content is constructed as an XML file, using a stylised format that is rendered by an xsl stylesheet. There are several stylesheets involved, the main one being ajhwebpage.xsl, but several others are used. The header and footer bars, for example, are rendered by the stylesheets ajhwebhead.xsl and ajhwebfoot.xsl, and the railway pages have their own stylesheet, ajhwebrail.xsl.

The main stylesheet, ajhwebpage.xsl, has various parameters that define the behaviour for the different rendering contexts. These are

The modification timestamp of the requested XML file. (The "Dynamically generated at" time in the footer box.)
The modification timestamp of the corresponding cached HTML file. (The "HTML cache rendered at" time below the footer box - only shown if different from the xmltime.)
The name of the file to be rendered.
The relative path to the current working directory, relative to the server home directory.
Today's date and time.
The name of the host machine on which this service is running. This name appears on the right of the '@' sign under "JOHN HURST" in the header line.
If set to true, forces debugging information to be printed along with the rendered file. The cache is updated.
Defines the current server name, as defined by the HTTP request. It does this by collecting the parameter 'server' passed in by the cgi script. This name appears on the left of the '@' sign under "JOHN HURST" in the header line.
Defines the current server URL for these web pages. It is qualified within the scripts by the addition of a subdirectory relative path, passed in through the script parameter $relcwd.
The version number of the script used to process this rendering. The value is passed into the script as a parameter by (Note: this is not valid for the train pages, as they are processed by a different script. An appropriate solution has not yet been developed.)
Note that the two server parameters are actually defined in a common script defineVars.xsl. The parameters are also common to ajhwebrail.xsl.

These renderings are applied by a cgi script,, invoked on every HTTP request for standard file types (XML, HTML, JPG, PNG, ...). XML files force a call on xsltproc, which uses the above XSL scripts to perform the rendering, and the result is cached as an HTML file.

The cache is updated whenever the XML file is seen to be more recent than the cached HTML file, although this can be confused if content changes in an included component (such as the header or footer bars) rather than the actual XML page file.

Page Hit Counts

Astute readers will have noticed that often the hit counts in the footer box and final trailer (if it appears) are different. Why is this? Well, the first one (inside the green box) is the XML file hit count, and the second one (below the green box) is the HTML hit count. These may be different, because the XML count counts the number of XML renderings, and the HTML count counts the number of HTML renderings (including the XML counts).

Whenever the XML file is more recent than the cached HTML, the XML file is re-rendered to HTML, the resultant HTML version is cached, the HTML count is cleared, and not displayed. Subsequent reloads that are satisfied by the cache increment only the HTML hit counter, and force its display.

You can force a reload of the page by clicking the railway image in the top left corner, or the "Made on a Mac" image in the bottom right corner. If neither of these icons are visible, then adding "?reload=true" to the end of the URL will also force a reload. This is often useful if the page appears not to be loaded correctly, or very out of date. Forcing a reload will eliminate the separate HTML page hit count.

The page hit count is stored in a separate file, which is created automatically if not found. This file is date stamped when it is created, and since such files occasionally get cleaned up, the time stamp (and hits since) will change when this happens. This accounts for the various date stamps that you will see across the pages.

This page is copyright, and maintained by John Hurst. 34 accesses all since
18 Feb 2022
My PhotoMy PhotoTrain Photo

Local servers: Localhost Newport Burnley Jeparit Reuilly Spencer (accessible only on local network.)
Public Web Servers: (not all may be active.)
Dynamically generated at 20231206:0601 from an XML file modified on 20220430:1739, by version 1.6.3.