VisezTrance

  • July 25, 2009 7:51 PM

    Creating a static website with XSLT

    By Daniel
    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. &#169; 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 files

    While 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.

    Tags:

    • xml,
    • xsl,
    • xslt
  • Monthly Archives

    • October 2013 (2)
    • May 2012 (1)
    • October 2011 (1)
    • September 2011 (2)
    • March 2011 (3)
    • February 2011 (1)
    • January 2011 (1)
    • September 2010 (1)
    • August 2010 (1)
    • June 2010 (1)
    • April 2010 (1)
    • December 2009 (1)
    • October 2009 (1)
    • September 2009 (1)
    • August 2009 (1)
    • July 2009 (2)
    • April 2009 (2)
    • February 2009 (1)
    • January 2009 (2)
    • December 2008 (1)
    • October 2008 (1)
  • Pages

    • About / Contact

2008, © Daniel Mircea