O'Reilly Hacks
oreilly.comO'Reilly NetworkSafari BookshelfConferences Sign In/My Account | View Cart   
Book List Learning Lab PDFs O'Reilly Gear Newsletters Press Room Jobs  


APACHE HACK

Allowing Simplistic User Preferences with SSI
A lot of sites offer the ability to change colors, to place columns on this side or that, or to open links in new browser windows. You have the need to do the same, but you don't want to create a server-side script in PHP, Perl or Python, and you don't want to use Javascript, fearing client side dependability. With SSI, you can minimally accomplish the same tasks.

Contributed by:
Morbus Iff
[03/14/03 | Discuss (0) | Link to this hack]

Prerequisites

  • The Server Side Include module (mod_includes) must be enabled.

By specifically coding your HTML pages to understand a single environment variables, you can offer the user various choices on page layout, as well as other browser feats. Careful consideration of links will allow the choices to follow the user around during the current session, or if they bookmark their choices. No cookies or tracking is involved.

The technique makes use the QUERY_STRING environment variable. QUERY_STRING's involve a question mark in the URL, like "http://www.disobey.com/this_is_a.shtml?query=string". They're a bit more flexible than the similar PATH_INFO, but have the downside of generally being ignored (not indexed) by search engines. This isn't too worrisome in this case, since many server side solutions afford the same illness.

The downside to this hack is that you can only use one "feature" at a time - if someone changes the background color to green, and then changes the link targets to "new window", the green color choice will be lost. Your best bet is to implement only one user choice at a time.

To start off our sorcery, create the following page, which we'll name index.shtml:

{{{
   <html>
   <head>
      <title>Apache Hack #12395 - SSI User Choices</title>
   </head>
   <body bgcolor="<!--#echo var="QUERY_STRING"-->">
     <h1>Eh oh!</h1>
   </body>
   </html>
}}}

Saving this file to your website and accessing URLs like:

{{{
   http://www.disobey.com/index.shtml?red
   http://www.disobey.com/index.shtml?blue
}}}

will change the background color load. Any piece of data on a webpage can be set and overridden in this way. Here's an example that will load a stylesheet based on the user's choice. The stylesheets could control a wider arrange of color changing besides just the background:

{{{
   <html>
   <head>
     <!--#if expr="\"$QUERY_STRING\" = \"\"" -->
     <link rel="stylesheet" type="text/css" href="white.css" />
     <!--#else -->
     <link rel="stylesheet" type="text/css" href="<!--#echo var="QUERY_STRING"-->.css" />
     <!--#endif -->
     <title>Apache Hack #12395 - SSI User Choices</title>
   </head>
   <body bgcolor="<!--#echo var="QUERY_STRING"-->">
     <h1>Eh oh!</h1>

     <ul>
       <li><a href="index.shtml?red">Red Background</a></li>
       <li><a href="index.shtml?green">Green Background</a></li>
     </ul>
   </body>
   </html>
}}}

The above also shows how to cater to an empty QUERY_STRING, which can happen if a user is coming to your pages for the first time. In this case, we use an if statement to check if QUERY_STRING is empty. If it is, then we load the default "white.css". Otherwise, we load whatever color stylesheet has been passed. We also give the user a choice of colors to play with. Clicking them will reload the current page with the chosen color background.

The key thing to remember is that if you want the preference to follow the user around to other pages, all links need to be constructed with the QUERY_STRING added to the end. To remember the color choice from above, we could add:

{{{
   <p><a href="help.shtml?<!--#echo var="QUERY_STRING"-->">Click here</a>!</p>
}}}

Now, assuming the help.shtml page understands and utilitizes the QUERY_STRING. the color choice will be remembered when the user changes the page. Constructing an entire design with QUERY_STRINGs like the above would create a site wide user configuration.

The technique isn't related to just colors - again, any piece of data on the page could be modified from the QUERY_STRING. The next example shows how to specify links to open up in a new window:

{{{
   <html>
   <head>
     <title>Apache Hack #12395 - SSI User Choices</title>
   </head>
   <body>
     <h1>Eh oh!</h1>

     <ul>
      <li><a href="index.shtml?_blank"
             target="<!--#echo var="QUERY_STRING"-->">New Window</a></li>
      <li><a href="index.shtml?_parent"
             target="<!--#echo var="QUERY_STRING"-->">Existing Window</a></li>
     </ul>
   </body>
   </html>
}}}

And finally, a more complex example of moving a box from the left side of the screen to the right side:

{{{
   <html>
   <head>
     <title>Apache Hack #12395 - SSI User Choices</title>
   </head>
   <body>
     <h1>Eh oh!</h1>

     <!--#if expr="\"$QUERY_STRING\" = \"\"" -->
     <table align="right" border="1" width="200"><tr><td>
       This the default location of the box.
       Place it on the <a href="index.shtml?left">left</a>.
     </td></tr></table>
     <!--#else -->
     <table align="<!--#echo var="QUERY_STRING"-->" border="1" width="200">
       <tr><td>The box is on the <!--#echo var="QUERY_STRING"--> side.
       Would you like to move it <a href="index.shtml?left">left</a>
       or <a href="index.shtml?right">right</a>?</td></tr>
     </table>
     <!--#endif -->
   </body>
   </html>
}}}

The above example starts to show a problem - duplication of data. To change the border of the table, you'd have to change it in two places - the default version (where QUERY_STRING is empty), and the QUERY_STRING'd version. To fix this, assign the QUERY_STRING to a variable, and set the default there:

{{{
   <html>
   <head>
     <title>Apache Hack #12395 - SSI User Choices</title>
   </head>
   <body>
     <h1>Eh oh!</h1>

     <!--#if expr="\"$QUERY_STRING\" = \"\"" -->
       <!--#set var="alignment" value="left"-->
     <!--#else -->
       <!--#set var="alignment" value="${QUERY_STRING}"-->
     <!--#endif -->

     <table align="<!--#echo var="alignment"-->" border="1" width="200">
       <tr><td>The box is on the <!--#echo var="alignment"--> side.
        Would you like to move it <a href="index.shtml?left">left</a>
        or <a href="index.shtml?right">right</a>?</td></tr>
     </table>
   </body>
   </html>
}}}

With techniques learned above and smart stylesheet choices, it's possible to create an entire site catered to the user's expectations - navigation bars on the left or right, colors to the visitor's palette, help systems seen or not seen, and so forth.

See also:


O'Reilly Home | Privacy Policy

© 2007 O'Reilly Media, Inc.
Website: | Customer Service: | Book issues:

All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.