Get More SSI Mileage With Conditionals

ITCWeb consists of thousands of pages that include common snippets of code for headers, footers and such via Apache’s Server Side Includes (SSI). It’s a fairly typical practice for creating templates since you just need to change a single file (the include) to immediately affect all the pages that include it. To maintain a consistent appearance across HTTP and HTTPS (SSL) protocols, our setup also connects the include files behind the scenes on the nonsecure and secure servers with symlinks. The practice worked flawlessly until we added the JavaScript for Google Analytics. The resolution required a little more SSI magic in the form of conditional expressions.

Google Analytics is a nifty, free site statistics package that collects user information such as browser type, screen width, etc. with minimal muss and fuss. Just insert code similar to the following (just before the closing body tag on your page) and Google handles the rest. The opening line loads the Google JavaScript that manages all the magic:

<script type="text/javascript" src="http://www.google-analytics.com/urchin.js"></script>
<script type="text/javascript">
  _uacct = "UA-123456-1";
  urchinTracker();
</script>

Since we wanted every page tracked, we added the Google code snippet to in our “footer” include file and went on our merry way. Unfortunately, as you may recall, the same footer include gets called from pages in the nonsecure and secure sites via the symlinks. Internet Explorer Security Information warning Scary error messages started popping up in Internet Explorer and "padlocks" broke in every other browser since the standard HTTP JavaScript file protocol (http://www.google-analytics.com…) didn’t mix well with the secure site’s HTTPS protocol—we needed to keep the protocols consistent (e.g., HTTPS JavaScript on the HTTPS server and HTTP JavaScript on the HTTP server).

Fortunately, Google has a special tracking code for secure sites. But dang it all if we don’t get the same error messages on our nonsecure site by using this new secure script in our old footer include. Too bad there isn’t a way to use conditional statements (e.g., if “on secure site” then “do this”, else “do that”) on a run-of-the-mill HTML Web page. Wait a second. There is—as long as we’re already using SSIs.

SSIs are good for more than including code snippets as we did with our footer include. They have a conditional expression vocabulary that we can tap into to resolve this little problem. Here then is the solution for the first line of code from above:

<!--#if expr="(${HTTPS})" -->
  <script type="text/javascript" src="https://ssl.google-analytics.com/urchin.js"></script>
<!--#else -->
  <script type="text/javascript" src="http://www.google-analytics.com/urchin.js"></script>
<!--#endif -->

Note that the expression checks for the existence of the HTTPS variable (#if expr="(${HTTPS})"). If it exists, then we know the HTTPS protocol is in use and we need to use the SSL version of the Google script. If the HTTPS variable doesn’t exist, we use the normal Google address. That’s it.

Granted, you may never come across such a Rube Goldberg scenario in your work, but there are plenty of other ways to twist server-variables and SSI conditionals to serve your purpose. They might just be the ticket for extending the reuse of your code.

6 Responses to “Get More SSI Mileage With Conditionals”

  1. Interesting!

    We use SSI in our websites (at work), as the CMS system we still use is working mostly with SSI and .shtml files… This tip might come handy, thx:)

    BTW, what about - can this syntax in SSI be used for something like this:
    http://alistapart.com/articles/keepingcurrent/

    …just instead of PHP/CSS yo umay use SSI/CSS? :-)

  2. Michel: Great point. I can’t speak for the performance differences, but you should be able to do everything in that article with SSIs as you would with PHP.

    <!--#set var="thisPage" value="About Us" -->
    <html>
    <head>
    <title>Company Name
      <!--#echo var="thisPage" --></title>
    <meta name="title" content="Company Name
      <!--#echo var="thisPage" -->" />
    </meta><meta name="keywords" content="
      <!--#echo var="thisPage" -->,
      company name, keyword1, keyword2, keyword3" />
    </meta></head>
    <style type="text/css">
    #navigation ul {
      list-style: none;
      margin: 0;
      padding: 0;
      }
    #navigation li {
      background: #ccc;
      border-left: 1px solid #999;
      float: left;
      margin: 0;
      padding: 0;
      }
    #navigation a {
      color: #666;
      font-weight: bold;
      padding: 5px 10px;
      text-decoration: none;
      }
    #navigation a:hover {
      color: #333;
      }
    #navigation #currentpage a {
      background: #fff;
      color: #333;
      }
    </style>
    <body>
    <div id="navigation">
      <ul>
        <li<!--#if expr="($thisPage=Page One)" -->
          id="currentpage"<!--#endif -->>
          <a href="#">Page One</a></li>
        <li<!--#if expr="($thisPage=Page Two)" -->
          id="currentpage"<!--#endif -->>
          <a href="#">Page Two</a></li>
        <li<!--#if expr="($thisPage=Page Three)" -->
          id="currentpage"<!--#endif -->>
          <a href="#">Page Three</a></li>
        <li<!--#if expr="($thisPage=About Us)" -->
          id="currentpage"<!--#endif -->>
          <a href="#">About Us</a></li>
      </ul>
    </div>
    </body>
    </html>

    Of course, in this enlightened era, we’d lean on CSS more to handle the navigation tabs. Create a new SSI variable, apply it to the body ID, tweak the last line of their CSS, and you end up with cleaner and more manageable code:

    <!--#set var="thisPage" value="About Us" -->
    <!–#set var=”thisPageID” value=”aboutuspage” –>
    <html>
    <head>
    <title>Company Name</title>
    <style type=”text/css”>
    #navigation ul {
      list-style: none;
      margin: 0;
      padding: 0;
      }
    #navigation li {
      background: #ccc;
      border-left: 1px solid #999;
      float: left;
      margin: 0;
      padding: 0;
      }
    #navigation a {
      color: #666;
      font-weight: bold;
      padding: 5px 10px;
      text-decoration: none;
      }
    #navigation a:hover {
      color: #333;
      }
    #pageonepage #pageone a,
    #pagetwopage #pagetwo a,
    #pagethreepage #pagethree a,
    #aboutuspage #aboutus a {
      background: #fff;
      color: #333;
      }
    </style>
    </head>
    <body id=”<!–#echo var=”thisPageID” –>”>
    <div id=”navigation”>
      <ul>
        <li id=”pageone”>
          <a href=”#”>Page One</a></li>
        <li id=”pagetwo”>
          <a href=”#”>Page Two</a></li>
        <li id=”pagethree”>
          <a href=”#”>Page Three</a></li>
        <li id=”aboutus”>
          <a href=”#”>About Us</a></li>
      </ul>
    </div>
    </body>
    </html>
  3. Thx, Steve!

    I’ll try some of your suggestions! Some things could be done via PHP, CSS, PHP+CSS or in a lot of other various ways (SSI, for example:-) Choose the best one which suits you… or the simplest one:)

    Good tips you share here, I’d like to test some of the code snippets soon… :)

  4. I’ll throw one more curve ball at ya: rather than manually adjust the opening two variables (thisPage and thisPageID) in every page, replace those two #set lines with a single include <!--#include file="page-switch.shtml" --> line. Then create the page-switch.shtml page with just the following code:

    <!--#if expr="$DOCUMENT_NAME = pageone.shtml" -->
      <!--#set var="thisPage" value = "Page One" -->
      <!--#set var="thisPageID" value = "pageonepage" -->
    <!--#elif expr="$DOCUMENT_NAME = pagetwo.shtml" -->
      <!--#set var="thisPage" value = "Page Two" -->
      <!--#set var="thisPageID" value = "pagetwopage" -->
    <!--#elif expr="$DOCUMENT_NAME = pagethree.shtml" -->
      <!--#set var="thisPage" value = "Page Three" -->
      <!--#set var="thisPageID" value="pagethreepage" -->
    <!--#elif expr="$DOCUMENT_NAME = aboutus.shtml" -->
      <!--#set var="thisPage" value = "About Us" -->
      <!--#set var="thisPageID" value = "aboutuspage" -->
    <!--#endif -->

    This page switching code matches up the current document name (provided by the server) with a pre-defined list of doc names before setting up the page variables. (FYI: more SSI server variables)

  5. Thank you! You throwed a lot of interesting valuable stuff at me, indeed:))) Thx again, now going to experiement :)

  6. Ben VanDenburg commented:

    If you want more information about SSI and all that can be done with the mod_include implementation of SSI, see http://httpd.apache.org/docs/2.0/mod/mod_include.html

Leave a Response

About Us

  • Building the University of Virginia web development community one passionate geek at a time.

Mailing List Sign-up

  • What's going on behind the scenes? Join the beTech mailing list and find out.
  • (listserv)

If you would like to write, present, or otherwise get more involved with beTech, please contact .


RSS feed icon