I'm exploring the XML -> XSLT -> HTML meme for producing web content. I have very little XSLT experience.
I'm curious what mechanisms are available in XSLT to handle abstractions or "refactoring".
For example, with generic HTML and a service side include, many pages can be templated and decomposed to where there are, say, common header, nav, and footer segments, and the page itself is basically the body.
The common markup languages, JSP, PHP, ASP, go as far as to allow all of those segments to have dynamic content (such as adding the user name to every header block).
JSP goes even farther by allowing you to create Tag files, which can accept arguments to be used when generating the content, and even surround and work on content within the tags themselves.
I'm curious similar functionality is done within XSLT. What facilities are there to make reusable block of XSLT for things like creating HTML pages?
For my own project, this is how I divided up my pages. There was a template.xsl file which was imported by each of my XSLs. Most pages just had template.xsl, but some pages such as cart, etc. needed their own because of the different kind of data they were parsing.
<page title="Home">
<navigation>
<!-- something here -->
</navigation>
<main>
<!-- something here -->
</main>
</page>
This is a snippet from my template.xsl. I threw in all the common stuff in here, and then gave the opportunity
for my pages to add their own information through call-template
.
<xsl:template match="/page" name="page">
<html>
<head>
<title><xsl:value-of select="(@title)" /></title>
<xsl:call-template name="css" />
<xsl:call-template name="script" />
</head>
<body>
<xsl:call-template name="container" />
</body>
</html>
</xsl:template>
An example of how my css tag would respond. Note that it calls css-extended.
css only
had the the common css' that would apply across all pages. Some pages needed more. Those
could override css-extended. Note that is needed because call-template
will fail if a
page calls a template but doesn't define it anywhere.
<xsl:template name="css">
<link rel="stylesheet" type="text/css" href="{$cssPath}reset.css" />
<link rel="stylesheet" type="text/css" href="{$cssPath}style.css" />
<link rel="stylesheet" type="text/css" href="{$cssPath}layout.css" />
<xsl:call-template name="css-extended" />
</xsl:template>
<!-- This is meant to be blank. It gets overriden by implementing stylesheets -->
<xsl:template name="css-extended" />
My container would work in a similar manner-- common stuff was defined and then each page
could just provide an implementation. A default implementation was in the XSL. (in content
)
<xsl:template name="container">
<div id="container">
<xsl:call-template name="header" />
<xsl:call-template name="content" />
<xsl:call-template name="footer" />
</div>
</xsl:template>
<xsl:template name="content">
<div id="content">
<div id="content-inner">
<xsl:call-template name="sideBar" />
<xsl:call-template name="main" />
</div>
</div>
</xsl:template>
<xsl:template name="main">
<div id="main">
<xsl:apply-templates select="main" />
<xsl:call-template name="main-extended" />
</div>
</xsl:template>
<!-- This is meant to be blank. It gets overriden by implementing stylesheets -->
<xsl:template name="main-extended" />
<xsl:template name="footer">
<div id="footer">
<div id="footer-inner">
<!-- Footer content here -->
</div>
</div>
</xsl:template>
It worked quite beautifully for me. If there are any questions I can answer for you, let me know.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With