XSLT comes to the rescue again! I have a small website of tutorials that uses the old Coppermine software. Each tutorial is a gallery. The first image of each gallery is the title of the tutorial, and the titles of subsequent images are "Step 1", "Step 2", etc. The description for each image explains how to do that step. I recently had to move my website to a new host that was incompatible with Coppermine. I quickly looked around for photo gallery software, but I found that much of it does not accommodate having a long description for each image. I needed to get my site back up quickly, and I didn't want to rush into choosing gallery software, so I made a quick gallery with the help of XSLT. First I dumped the data from the Coppermine database to produce XML for each page that looked like this:
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet href="/../gallery.xsl" type="text/xsl"?> <page> <title>Step 1</title> <image>LRG-20100804-001.jpg</image> <text><p>This is the first step in this process.</p> <p>Be <em>very</em> careful to follow these instructions.</p> </text> <next>page2</next> <prev>page0</prev> </page>
Most of this I could do using an SQL select statement with the CONCAT()
function and appropriate literals. I added the <next>
and <prev>
elements manually. The data was saved in files named page0.xml
, page1.xml
, etc, with a separate directory for each tutorial. The gallery XSLT stylesheet, which was saved in the parent directory so that it could be shared by all the tutorials, looked like this:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html" indent="yes"/> <xsl:template match="/"> <html> <head> <title> <xsl:value-of select="page/title"/> </title> <style> .icon { width:50px; height:50px; border-style:none; } </style> </head> <body> <h1> <xsl:value-of select="page/title"/> </h1> <!-- Image --> <div> <xsl:element name="img"> <xsl:attribute name="src">images/ <xsl:value-of select="page/image"/> </xsl:attribute> </xsl:element> </div> <div> <xsl:copy-of select="page/text"/> </div> <!-- Navigation buttons --> <div> <xsl:if test="page/next"> <xsl:element name="a"> <xsl:attribute name="href"> <xsl:value-of select="page/next"/> </xsl:attribute> <img src="/icons/next.png" class="icon" style="float:right;"/> </xsl:element> </xsl:if> <xsl:if test="page/prev"> <xsl:element name="a"> <xsl:attribute name="href"> <xsl:value-of select="page/prev"/> </xsl:attribute> <img src="/icons/back.png" class="icon" style="float:left;"/> </xsl:element> </xsl:if> </div> </body> </html> </xsl:template> </xsl:stylesheet>
The result was a quick gallery with buttons to go forward and backwards through the tutorials. Now, there are some disadvantages to implementing a gallery this way. By using stylesheets that are processed in the user's browser, you are at the mercy of how each different browser implements XML stylesheets. Also, processing the individual files this way makes it trickier to do things that require looking at all of them, like automatically generating an index of tutorials, or generating "page x of y" page numbers. And finally, it would be nice if I could have avoided manually adding the <next>
and <prev>
tags. I am in transition between host sites, so my Marklogic server was not available, but if it had been, I could have used an XQuery program to look at the <title>
elements and insert the appropriate <next>
and <prev>
elements using the xdmp:node-insert-child()
function. But if my Marklogic server had been available, I probably would have just done the whole thing using XQuery. Still, the way I have the tutorials XML-ized now, it will be easy to use XQuery to convert them to whatever form I need, either to serve them from the Marklogic server using XQuery, or to convert them for some gallery package, if I find one I like.