Server Side Includes
Overview
Server Side Includes (SSI) are a powerful way of embedding
dynamic content in your web pages. SSI documents are parsed
by the server before being sent to the client. This allows
you to embed SSI tags within HTML pages which are expanded by
the server before being sent to the client. The Zeus server
has an exceptionally flexible SSI engine which can expand SSI
tags, regardless of how the HTML was generated. The Zeus SSI
engine is optimised so SSI documents do not degrade the
performance of the server.
SSI enabled HTML files require a MIME type of
text/x-server-parsed-html which by default is mapped on
to the .shtml file extension. Any output generated
which has a MIME type of text/x-server-parsed-html
will be parsed by the server, whether it is from a static
file, a CGI script or a Java Servelet.
SSI Directives
SSI Directives are special values in your HTML files which
the server will look for to parse. In order not to interfere
with your HTML design the SSI directives are included in HTML
comments. HTML comments have a special starting tag
"<!-->" and ending tag "-->"
<!-- HTML Comments look like this -->
SSI directives contain a command, and a number of
parameters and arguments. So they take the form :
<!--#command parameter(s)="argument"-->
The #echo Command
The echo command makes available the set of
environment variables sent to CGI programs. Using this
command you can send these variables back to the user without
having to resort to CGI programs. The echo command
is followed by the parameter and argument values
"var=environment variable". For a full list
of environment variables see the CGI documentation.
The following SHTML file displays a selection of SSI
variables.
<html>
<head>
<title>SSI Variables</title>
</head>
<h1>SSI Environment Variables</h1>
<pre>
SERVER SOFTWARE : <!--#echo var="SERVER_SOFTWARE"-->
GATEWAY_INTERFACE : <!--#echo var="GATEWAY_INTERFACE"-->
SERVER_PROTOCOL : <!--#echo var="SERVER_PROTOCOL"-->
SERVER_NAME : <!--#echo var="SERVER_NAME"-->
SERVER_PORT : <!--#echo var="SERVER_PORT"-->
REQUEST_METHOD : <!--#echo var="REQUEST_METHOD"-->
REMOTE_HOST : <!--#echo var="REMOTE_HOST"-->
HTTP_USER_AGENT : <!--#echo var="HTTP_USER_AGENT"-->
DATE_LOCAL : <!--#echo var="DATE_LOCAL"-->
DATE_GMT : <!--#echo var="DATE_GMT"-->
</pre>
</body>
</html>
Will result in something similar to the following being sent
to the client:
<html>
<head>
<title>SSI Variables</title>
</head>
<h1> SSI Environment Variables </h1>
<pre>
SERVER SOFTWARE : Zeus/3.0
GATEWAY_INTERFACE : CGI/1.1
SERVER_PROTOCOL : HTTP/1.0
SERVER_NAME : www.zeus.co.uk
SERVER_PORT : 80
REQUEST_METHOD : GET
REMOTE_HOST : pc203.zeus.co.uk
REMOTE_ADDR : 10.0.0.14
HTTP_USER_AGENT : Mozilla/4.0b5 [en] (Win95; I)
DATE_LOCAL : 06:12:16 PM 06/02/97
DATE_GMT : 05:12:16 PM 06/02/97
</pre>
</body>
</html>
The
#include Command
Managing a complex web site can be a considerable task,
particularly if you wish to maintain a common look and feel
through out all the pages. Including a common footer or
navigation bar to your site helps your visitors identify
where they are and helps them move quickly to the information
they need. However if you then need to change the footer, you
would need to update every page on your site. By using SSI to
insert a file at the end of each of your pages you would only
need to change one file.
The SSI directive include allows us to merge other
files into our HTML pages. It is followed by the parameters
file or virtual. file specifies a
filename relative to the current directory, virtual
can specify a relative filename or an absolute URL within the
whole document root for the virtual server.
<!--#include virtual="/dir/filename"-->
<!--#include file="filename"-->
Going back to our original scenario, displaying a common
footer for all your documents is now easy. Each page on your
server will reference the same document via the
include SSI directive.
A .shtml file:
<HTML>
<HEAD><TITLE>SSI Test</TITLE></HEAD>
<BODY>
<P> This is my text from index.shtml <P>
<!--#include virtual="/includes/footer.html"-->
</BODY>
</HTML>
The /includes/footer.html file :
Please email <a href="mailto:harry@mycompany.co.uk"> Harry</a> for
more details on our products.
Will result in the following output being set to the client:
<HTML>
<HEAD><TITLE>SSI Test</TITLE></HEAD>
<BODY>
<P> This is my text from index.shtml <P>
Please email <a href="mailto:harry@mycompany.co.uk">
Harry</a> for more details on our products.
</BODY>
</HTML>
The #fsize
and #flastmod Commands
The #fsize command will insert the size of the specified
file into the document. There are occasions when you may want
a visitor to your web site to download information which
could be substantial in size. In these cases it is polite to
include the file size in the document so the visitor can
estimate how long the download will take. You could include
the file size directly in the HTML, but if the files were to
change you would need to update the HTML pages as well. The
#fsize command allows you to include the size of files which
may change regularly.
The #fsize command is followed by the parameters
file or virtual with the same meaning as the
#include command described above. Each parameter take a file
location as an argument.
The #flastmod command works in the same manner returning the
data the file was last modified.
By using the recursive nature of the Zeus SSI engine it
would be possible to generate a file listing from a CGI
script, but obtain the file sizes and modification dates via
the SSI commands.
Example : File Size of Downloads
A University publishes hourly satellite pictures on the web.
Due to the difference in time and weather, combined with the
effect of the compression code, the size can alter
considerably. Using the #fsize and #flastmod commands the web
page always has the correct information displayed.
The .shtml file:
<html>
<head>
<title>Pictures</title>
</head>
<body>
<h1>Satellite Pictures</h1>
Please download the <a href="picture.jpg">picture, it is only
<!--#fsize file="picture.jpg"--> in size. <br>
Last updated on <!--#flastmod file="picture.jpg"-->
</body>
</html>
Will result in something similar to the following being sent
to the client:
<html>
<head>
<title>Pictures</title>
</head>
<body>
<h1>Satellite Pictures</h1>
Please download the picture, it is only 4.8Kb in size.
Last updated on 05:52:21 PM 06/03/97
</body>
</html>
The #config
Command
The #config command can be used to change the output format
of certain SSI directives, specifically those which return a
time / date or a filesize. This allows you to use a more
understandable format than the defaults for your particular
application.
The #config command takes two parameters, timefmt to modify
the date and time formats, and sizefmt to modify the file
size format.
The timefmt parameter takes a free form text string of
tokens as an argument in a similar vein to the UNIX library
call strftime. These tokens are expanded by the
server to produce the desired time format.
| %a |
Day : abbreviated |
Mon, Tue, Wed |
| %A |
Day |
Monday, Tuesday |
| %b |
Month : abbreviated (%h) |
Jan, Feb, Mar |
| %B |
Month |
January, February |
| %C |
Year : Without Century |
"00" - "99" |
| %d |
Day of Month |
"01" - "31" |
| %D |
Date : mm/dd/yy |
"01/01/00" - "12/31/99" |
| %e |
Day of Month : Single figures |
"1" - "31" |
| %h |
Month : abbreviated (%b) |
Jan, Feb, Mar |
| %H |
Hour of Day : 24 hour clock |
"00" - "23" |
| %I |
Hour of Day |
"01" - "12" |
| %j |
Julian Day of Year |
"001" - "366" |
| %m |
Month of Year |
"01" - "12" |
| %M |
Minute |
"00" - "59" |
| %n |
Newline character |
|
| %p |
AM or PM |
"AM" | "PM" |
| %r |
Time in %I:%M:%S %p |
"00:00:00 am" - "12:59:59 pm"
|
| %R |
Time in %H:%M |
"00:00" - "23:59" |
| %S |
Seconds |
"00" - "61" |
| %t |
Tab character |
|
| %T |
Time in %H:%M:%S |
"00:00:00" - "23:59:59" |
| %u |
Numbered Day of the Week : Starting with
Monday = 1 |
"1" - "7" |
| %w |
Numbered Day of the Week : Starting with
Sunday = 0 |
"0" - "6" |
| %y |
Year : Without Century |
"00" - "99" |
| %Y |
Year |
"0000" - "9999" |
| %Z |
Time Zone |
"GMT", "BST", "CST" .. |
| %% |
Percentage Character |
|
Sophisticated time and date information can be constructed
using these tokens. Additional text can also be included in
the string, allowing additional explanation.
The sizefmt parameter takes an argument of either
bytes or abbrev. The bytes value will
cause all filesize information to be displayed exactly in
bytes, while the abbrev value will display an
approximate value with the units appended (Kb, Mb,
Gb).
Example : Formatting The Date
Displaying a date on the welcome page for your site is quite
a common requirement, but you probably don't want to got to
all the trouble of writing a CGI script to display the whole
page. You also probably don't want to use the default time
format either. Using #config and the SSI environment variable
date_local we can easily display the time in the way
we want.
The .shtml file:
<html>
<head>
<title>SSI Date Test</title>
</head>
<body>
The current time is :
<b><!--#echo var="DATE_LOCAL"--></b>
<br>
But the time looks nicer this way :
<!--#config timefmt="It's <b>%A</b> and the time is <b>%I:%M %p</b>!"-->
<!--#echo var="DATE_LOCAL"-->
<hr>
</body>
</html>
Will result in something similar to the following being sent
to the client:
<html>
<head>
<title>SSI Date Test</title>
</head>
<body>
The current time is :
<b>08:00:35 PM 06/02/97</b>
<br>
But the time looks nicer this way :
It's <b>Monday</b> and the time is <b>08:00 PM</b>!
<hr>
</body>
</html>
We are even able to include HTML tags in text string which
defined the date.
The #exec
command
There are occasions when SSI includes and SSI variables
cannot achieve the dynamic content you want, but still don't
want to go to the trouble of writing a CGI program to
generate the entire page content. By using the #exec command,
you can include the output of a program within your HTML
pages. The exec command is followed by the
cgiparameter, and a valid CGI program as the
attribute.
<!--#exec cgi="prog.cgi" -->
Example : A CGI to Display Machine Load
To prove that your server machine is capable you might want
to include a load meter on the machine spec page. The page
contains a lot of information and is updated frequently so
you don't want a CGI program to generate the complete HTML
code. The examples below will obtain the load average of the
machine, then determine what colour to display the text.
A .shtmlfile :
<HTML>
<HEAD><TITLE>SSI Test</TITLE>
<META HTTP-EQUIV="Refresh" CONTENT="2; test.shtml">
</HEAD>
<BODY>
This is a big page about our large machine. <p>
<!--#exec cgi="load.cgi"-->
</BODY>
</HTML>
The CGI Program:
#!/usr/bin/perl
print "Content-type: text/html", "\n\n";
$uptime = `uptime`;
@fields = split /,/, $uptime;
$load = @fields[$#fields-1];
print "<p>";
if ($load < 1) {
$colour = "white";
}
elsif ($load < 2) {
$colour = "yellow";
}
elsif ($load < 3) {
$colour = "orange";
}
else {
$load ="red";
}
print "Load average is :<FONT color = $colour> ", $load, " </FONT>\n";
print "<p>", "<HR>", "\n";
exit 0
Possible (this is dynamic after all) result in the HTML:
<HTML>
<HEAD><TITLE>SSI
Test</TITLE>
<META HTTP-EQUIV="Refresh"
CONTENT="2; test.shtml">
</HEAD>
<BODY>
This is a big page about our large machine. <p>
<p>Load average is :<FONT color = white> 0.32 </FONT>
<p><HR>
</BODY>
</HTML>
Executing arbitrary shell commands
The exec command can also be used to execute arbitrary shell
commands when used with the cmd= tag. For this tag
to be available, the server needs to have `CGI enable
anywhere' turned on.
<!--#exec cmd="command"-->
The server will execute the equivalent of /bin/sh -c
"command" and replace the tag with the output of that
command.
For example:
<!--#exec cmd="cat /etc/passwd | cut -f1 -d':' | sort"-->
The #set
command
The #set command allows you to add your own variables that
can be used with the #echo command. For format of a #set
command is:
<!--#set var="..." value="..." -->
For example:
<!--#set var="title" value="My document's title" -->
The #set command is extremely powerful as it provides a means
of passing 'arguments' to recursively included SSI pages.
This is because the #set command adds to the global variable
environment, so a parsed document can set a variable then
include another parsed document which uses this variable, or
vice versa. For example:
File title.shtml:
<!-- requires title -->
<!-- Imagine this is a complicated table -->
<!-- which puts the title at the top of -->
<!-- the page in a standard fashion. -->
<html>
<head>
<title><!--#echo var="title"--></title>
</head>
<body bgcolor=#ffffff>
<table bgcolor=#f0f0c3 cellspacing=4>
<tr>
<td>
<font size=+3>
<!--#echo var="title"-->
</font>
</td>
</tr>
</table>
Then we could use this complex standard title in a document
"About Zeus" as follows:
<!-- Set title, and include standard document header -->
<!--#set var="title" value="About Zeus"-->
<!--#include file="title.shtml"-->
Document body goes here.
<!-- We'd probably do the footer in the -->
<!-- same way, but for now we'll just -->
<!-- terminate the html manually. -->
</body>
</html>
Using the #set command allows the reuse of 'components' of
HTML and is extremely useful in large web-site design.
|