Hello everyone,
I was wondering if there is a good approach in XSLT stylesheet design pattern to separate common and specific data representation.
I was trying, but got very confused and lost. I would appreciate any advice, tips, hints where I can read up on how to better separate XSLT stylesheets. And also, would really appreciate help with the example below as it doesn't work =/ THANK YOU!
I need to create a variety of HTML docs with different looks that would reuse some of the data. For example date of a document, signature details (name, job title) and so on. Also, I'm using quite a lot of global variables (because XML isn't structured well and data reused throughout a doc).
What I was trying to do, is to move all the templates that would create a common HTML structure in one stylesheet and then all specific bits will be in their own stylesheet.
Something like the following:
Common templetes stylesheet "commonTemplates.xsl"
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Variables Local -->
...
<xsl:output method="html" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
doctype-system="http://www.w3.org/TR/html4/loose.dtd" indent="yes" />
<xsl:template match="/Bookings">
<html>
<head>
<!-- populated by a template in a specific stylesheet -->
<title><xsl:call-template name="docTitle"/></title>
</head>
<body>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<!-- general template for date -->
<xsl:template match="/Bookings/Booking" name="docDate">
<p class="date"><xsl:value-of select="./@Date"/></p>
</xsl:template>
<!-- general template for signature -->
<xsl:template match="/Bookings/Booking/Users" name="signature">
<xsl:param name="signatureLine" select="'Yours sincerely,'"/>
<div id="signature">
<p><xsl:value-of select="$signatureLine"/></p>
<p class="details">
<!-- populated by a template in a specific stylesheet -->
<xsl:apply-templates select="." mode="signature"/>
</p>
</div>
</xsl:template>
<!-- dummy templates signatures otherwise it complains that there is no such template -->
<xsl:template name="docTitle"/>
</xsl:stylesheet>
Specific templetes stylesheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Imports -->
<xsl:import href="commonTemplates.xsl"/>
<!-- BODY CONTENT OF HTML PAGE -->
<xsl:template match="/Bookings/Booking">
<xsl:call-template name="docDate"/>
<!-- document's content -->
<div>
<xsl:call-template name="content" />
</div>
</xsl:template>
<xsl:template name="docTitle">
<xsl:text>Here is the document title</xsl:text>
</xsl:template>
<!-- some content at the end of which signature should be inserted -->
<xsl:template name="content">
<p>SOME CONTENT</p>
<xsl:apply-templates />
</xsl:template>
<!-- specific rule to insert appropriate data for signature -->
<xsl:template match="/Bookings/Booking/Users" mode="signature">
<span class="name"><xsl:value-of select="./@Name"/></span>
<span class="job"><xsl:value-of select="./@Title"/></span>
</xsl:template>
</xsl:stylesheet>
Unfortunately, the template for signature doesn't work and I can't figure out why :( It does for the docTitle though.
The results HTML looks like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<p class="date">16 February 2010</p>
<div id="secondDeposit">
<p>SOME CONTENT</p>
<!-- here I get lots of empty space -->
</div>
</body>
I was wondering if such idea could be implemented in general and how to do it properly, obviously mine doesn't work.
Also, which approach will be better in this case: include or import stylesheet? I think with one of them I don't need to list all the variables again.
I would appreciate any help! Sorry for a long post and if it's not as clear.
Thank you!