A static website usually has a common layout and unique content across
pages. Changing the layout means changing every page - and it does
happen, perhaps you have to add a javascript tracking code or correct a
minor typo - a daunting task for something so trivial. It's really no
wonder that most developers use SSI or php includes to ease this task.
I'm
going to show you an alternate way of separating your content from the
actual layout without using any server side code, by using XSLT.
Before venturing any further, here is what you should know:
Pros:
-
No server side coding. Just copy the code on any server and it will
work. Your server will still have to display the proper index file
though (index.xml).
- It's fast. Especially if you're running a server that handles static files very fast such as lighttpd or nginx
Cons:
-
SEO impaired. It's xml so it's easier to parse, yet it will probably
rank lower because the XSL code may not be properly parsed by all
search engines
- limited to browsers that support XSLT. Unless you
are concerned about Links or Konqueror this is a non issue. Major
browsers that support it include: Firefox, IE6+, Safari, Chrome, Opera
If you're still with me let's begin.
Create an xml file named index.xml. Paste the following code:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="layout.xsl"?>
<page>
<content>
<p>
Welcome.<br />
This is the default home page.
</p>
</content>
</page>
The
content tag represents the unique code that it will change from page to
page while the actual layout will be handled by the xsl file defined on
the second row.
Create a file named layout.xsl and paste the following code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" />
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="container">
<div id="header">
<h1>My Website</h1>
<ul class="navigation">
<li>
<a href="index.xml">Home</a>
</li>
<li>
<a href="about.xml">About</a>
</li>
<li>
<a href="contact.xml">Contact</a>
</li>
</ul>
</div>
<div id="content">
<xsl:copy-of select="page/content" />
</div>
<div id="footer">
<p>Lorem ipsum dolor sit. © 2009</p>
</div>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Look
over the xsl output statement. It's set to html in order for the
browsers to render the xml file as an html; additionaly we set a
doctype. This is particulary important for Internet Explorer. Omitting
the doctype will trigger quirks mode.
Inside the content div we get
the actual page content. You probably noticed the use of the "copy-of"
element. The difference between it and "value-of" is that it copies the
entire node, preserving the html tags inside, unlike the latter.
Let's style the page.
* {
margin: 0;
padding: 0;
}
a {
color: #00f;
}
ul li {
list-style-type: none;
}
body {
background-color: #fff;
font-family: arial, sans-serif;
line-height: 18px;
font-size: 12px;
color: #333;
}
#container {
width: 940px;
margin: 20px auto;
padding: 15px 10px;
border: 1px solid #ccc;
background-color: #eee;
}
#container #header h1 {
font-size: 50px;
margin: 10px 0 30px 0;
}
#container #header ul.navigation li {
display: inline;
}
#container #header ul.navigation li a {
display: block;
float: left;
padding: 10px;
border: 1px solid #000;
margin-right: 10px;
text-decoration: none;
color: #000;
}
#container #header ul.navigation li a:hover,
#container #header ul.navigation li a.selected {
background-color: #fff;
}
#container #content {
clear: left;
padding: 30px 0;
}
#container #footer {
font-style: oblique;
}
As
it turns out static layouts are not that static. The page title should
change across pages, and the navigation menu should highlight the
current page item.
Inside our index.xml file, we'll add these
properties. I'm assigning them as attributes, but these could had very
well been tags.
<page title="Welcome" selected-navigation-item="home">
Next, back in our xsl file, inside the head tags add the title:
<title><xsl:value-of select="page/@title"/></title>
For the menu we'll have to add the selected class for current navigation item:
<ul class="navigation">
<li>
<a href="index.xml">
<xsl:if test="page/@selected-navigation-item = 'home'">
<xsl:attribute name="class">selected</xsl:attribute>
</xsl:if>
Home
</a>
</li>
<li>
<a href="about.xml">
<xsl:if test="page/@selected-navigation-item = 'about'">
<xsl:attribute name="class">selected</xsl:attribute>
</xsl:if>
About
</a>
</li>
<li>
<a href="contact.xml">
<xsl:if test="page/@selected-navigation-item = 'contact'">
<xsl:attribute name="class">selected</xsl:attribute>
</xsl:if>
Contact
</a>
</li>
</ul>
Create the about.xml and contact.xml files by using the index.xml file.
This wraps it up.
-
The final result-
Download filesWhile
this approach does have it's fair share of downsides I think it's an
interesting way of code separation that may be worth taking a closer
look.