Webmaster's Guide to Server Side Includes | 2
[previous] |
Webmaster's Guide to Server Side Includes
Conditional SSI
Most of the commands above are useful, but still haven't scratched the surface of the power of SSI. What if you are having trouble with CSS/browser incompatibility and need some relief? This kind of problem is perfect for conditional SSI. Conditional SSI use the same if/else control structures that many other programming languages use. However, since HTML doesn't have logic of its own, the if/else statements need to be commented out, just like in other SSI directives. Here is an example of a Conditional SSI that displays one style sheet for non -MSIE version 4 browsers (Netscape 4) and another style sheet for all other browsers.
<!--#if expr="(${HTTP_USER_AGENT} = /Mozilla\/4/) && (${HTTP_USER_AGENT} != /MSIE/)" -->
<LINK rel="stylesheet" type="text/css"
href="netstyle.css">
<!--#else -->
<LINK rel="stylesheet" type="text/css"
href="nonnetstyles.css">
<!--#endif -->
When looking at this example, first notice the <!--#endif --> directive at the end of the conditional logic. The meaning of this directive is obvious; however, note that the logic won't work if <!--#endif --> is left off. The other thing to notice is that the "if" statement says, "if Mozilla 4 and not MSIE(Internet Explorer or Opera)." The "not Internet Explorer" part is necessary since the HTTP_USER_AGENT value for IE 4 and above contains the string Mozilla/4.0. To make things a little clearer, here is the output of the HTTP_USER_AGENT environment variable for Internet Explorer 5.5:
Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)
and Opera 5: [but only when Opera is set to IE compatibility mode - Ed.]
Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.0) Opera 5.02 [en].
To output the value of the HTTP_USER_AGENT variable to your browser you can use the echo command mentioned above.
The browser example above can easily be extended; consider the case where you want three different style sheets for three different environments. Let's say you want one style sheet for all HTML files displayed in Netscape, one for HTML files in your /graphics directory when displayed in non-Netscape browsers and one for HTML files in all other directories when displayed in non-Netscape browsers.
<!--#if expr="(${HTTP_USER_AGENT} = /Mozilla/) && (${HTTP_USER_AGENT} != /MSIE/)" -->
< !--#include virtual="netstyle.css">
<!--#elif expr="${DOCUMENT_URI} = /^\/graphics\/.*/"-->
< !--#include virtual="graphstyles.css">
<!--#else -->
< !--#include virtual="nonnetstyles.css">
<!--#endif -->
There can only be one else directive in each if/else control structure. If you want more conditions you need to use the elif directive. Unlike the else directive, the elif directive can be used as many times as you like. In addition, the syntax of the elif directive is more similar to the if directive than it is to the else directive. The elif directive takes arguments just like the if directive. In the example above the DOCUMENT_URI environment variable is used to match the /graphics directory. Note that you can use regular expressions in conditional SSI statements. Note also that the style sheets are embedded style sheets saved as separate SSI, instead of linked style sheets like in the first example
On Including an Include
By now you can probably see the power of SSI, but you're thinking, "what if I want to include an include in an include?" The answer is, "you can and it'll work" and you can include an include in an included include too. You can recursively include includes until your server cuts you off. That is, the number of layers of inclusion you are allowed is determined by a setting in the config files of your Web server. While it might be fun to think about infinite levels of inclusion, it certainly won't help the performance of your Web site. I know from experience that two layers of inclusion won't cause a problem. Here's an extension to the style sheet example above using two layers of inclusion. Say you don't want to include the long list of directives below in your HTML page:
<!--#if expr="(${HTTP_USER_AGENT} = /Mozilla/) && (${HTTP_USER_AGENT} != /MSIE/)" -->
<!--#include virtual="/netstyle.css">
<!--#elif expr="${DOCUMENT_URI} = /^\/graphics\/.*/"-->
< !--#include virtual="graphstyles.css">
<!--#else -->
< !--#include virtual="nonnetstyles.css">
<!--#endif -->.
Instead, you could save the long list in a file named include.html. Then you could include the below directive in place of the long list above in your HTML page:
<!--#include virtual="/directory/include.html" -->
The end result of the doubly included file will be the same as the first triple style sheet example. But in this case, you will have made your site easier to maintain by putting your logic and style sheet names in an external file. This way, if you change the logic or name of your style sheets, you only need to edit one file instead of many. Again, the benefits of SSI are easily recognizable. However, be careful when you write SSI.
Common Pitfalls
There are two common pitfalls when trying to use SSI.
- People usually put a space between the <!-- and the #. If you add this space your SSI won't work.
- People forget that SSI depend on both Web server type and configuration. Remember, if your server is configured to only parse SSI in files with a .shtml extension and you save your HTML page with include directives as .html, your SSI won't be parsed by the server and consequently won't work.
Summary
In conclusion, SSI are a very useful tool for Web development. SSI can provide simple dynamic content without the use of CGI or ASP. SSI allow you to make site-wide changes by updating only one include file. In addition, SSI syntax has simple branching logic allowing you to tailor your Web pages to the environment in which they are displayed.
Further Reading
Here are some links to some useful tutorials on SSI in you are interested in knowing more.
Regular SSI Reading
NCSA HTTPd Server Side Includes (SSI)
Conditional SSI articles
University of Kansas Academic Computing Services
Leland conditional SSI extensions
Alexander Rylance is Assistant Editor for WebReference.com. Prior to working for WebReference he was a Java T.A. at the University of Michigan - Ann Arbor and a Business Analyst at Banc of America Securites. His primary interests are Web Development, Asian culture and pretty much anything to do with the Internet. He can be contacted at: [email protected]
[previous] |
Created: March 30, 2001
Revised: March 30, 2001