Simplifying your site with Server Side Includes
Inclusion
Server Side Includes (SSIs) can save you time and make your website easier to maintain.
Most websites have a handful of elements that are common to all or most pages, such as headers, footers, and menus. Hard-coding these sections into each page means that if you ever make any changes, you have to edit every single page, which is very tedious and not a good use of your time. Server Side Includes (SSIs) are an easy way of writing HTML snippets once only and then including them in your pages with a single reference.
Writing the Include File
Before setting up the web server to handle SSIs, I'll start by defining some SSI content. Listing 1 shows a basic footer include file, containing just the footer information I want at the bottom of each page. (The styling is all in the CSS, which I'm not showing here – this is just the HTML logic. It is always good practice to separate content logic from presentation and styling.)
Listing 1
Basic Footer Include File footer.html
As shown in Listing 2, I find it best to create a directory for includes in the web server's root directory. This approach helps you keep track of the include files and avoid confusing them with your regular HTML files. An organized directory is particularly important for files that apply to the whole site; if you have includes that are specific to a particular subdirectory, you might want to keep them with that subdirectory.
Listing 2
Setting Up an Includes Directory
The web server doesn't serve the include file directly; instead, you use it by including a reference to it in a regular HTML file. The contents of the include file will effectively be dumped straight into the HTML file in place of the reference (without any actual change to the file on the disk; the alterations are made on the fly as the page is served up).
Now I need to set up a test HTML file that includes this footer file, as in Listing 3. Note the .shtml ending – I'll discuss this ending in the next section, and don't try viewing this file in your browser yet! It won't work until the web server is set up correctly. The syntax used for the reference here (the single line starting <!--#include) is the standard syntax for an SSI reference.
Listing 3
test.shtml
Setting Up Your Web Server
At this point, the files are set up, but the server can't serve them correctly – if you look at the test.shtml file, the footer won't be in it. To get it running correctly, you need to set up your web server (here, I'm using Apache, but other servers can also deal with SSIs).
The first step is to enable the include module, which lets Apache deal with SSIs. In a Debian/Ubuntu system, use a2enmod include; otherwise, add the line in Listing 4 to your /etc/apache/apache2.conf file (you might need to edit the path to the module if your configuration is non-standard).
Listing 4
Add This Line to apache2.conf
Apache now can parse SSIs, but you need to tell it to permit the parsing of SSIs. To do this, add an Options +Includes directive within the directory in which you want SSIs to work. In Listing 5, this is the main directory, /var/www/.
Listing 5
Allowing Apache to Parse SSIs
Note that if you have specific settings for subdirectories of this directory that do not use the + syntax to set their other options, Apache will override the Includes option. With Apache Options, putting + in front of an option means "add this to any existing or inherited options," whereas leaving off the + means "replace any existing or inherited options with this set of options." (Using a - in front of the Option means "remove this option.")
So in Listing 5, the /var/www/main/ directory will not have Includes set (only FollowSymLinks), whereas /var/www/secondary/ will have both Includes and Indexes set.
Once you've set the Options correctly on your directories, the final step is to tell Apache which files to parse. Unless you're certain that all your files really do have SSIs, you don't want it just to parse every single file because it will slow down the delivery of files that don't have any SSIs included.
One way to tell Apache where to look for files is to treat any that end with .shtml as those to parse for SSIs. To do this, add the two lines shown in Listing 6 within the <Directory> tags set up in Listing 4.
Listing 6
Parsing .shtml Files for SSIs
Now reload your server (with /etc/init.d/apache2 force-reload) and go look at your test.shtml page with a browser. You should see your first page with SSIs (Figure 1).
The downside to this approach is that you have to rename any existing files in which you want to use SSIs as .shtml files in order for them to be parsed correctly. Alternatively, you can tell your server to rewrite all .html files as .shtml files by enabling the rewrite module (a2enmod rewrite) then adding the lines in Listing 7 within the <Directory> tags.
Listing 7
Enabling the rewrite Module
However, this approach is tantamount to just telling the server to parse all .html files for includes, which will have performance implications. You could also use find and xargs to change all your .html files to .shtml and then manually change back any that shouldn't be treated in this way.
The alternative is to use the XBitHack option. Instead of the two lines in Listing 6, add the following line inside the <Directory> tags in Listing 5:
XBitHack on
This directive tells Apache that any file with the execute bit set should be parsed for SSI directives. To check out your test file, change its execute mode with chmod +x test.html. (Then do that to any other files in which you want to use SSI directives.)
Note that you should use either the method shown in Listing 6 or the XbitHack directive – but not both!
Now reload Apache with /etc/init.d/apache2 force-reload, and try loading your test file by pointing your browser at http://www.mysite.com/test.shtml (or test.html if you've used the XBitHack directive).
Further Uses of SSIs
One very useful thing you can do with SSIs is nest them, so an include file can include a reference to another include file. An example of this might be when you want to have a menu with submenus that are included on every page (Figure 2; see Listings 8 and 9).
Listing 8
Main Menu Include File menu.shtml
Listing 9
Submenu Include File aboutmenu.html
Note that you'll need to set up menu.shtml to be parsed – either, as here, by using a .shtml extension or by using XBitHack and setting the execute bit as described previously.
SSIs also support various other commands and variables. For example, to output today's date, use:
<!--#echo var="DATE_LOCAL" -->
The DATE_LOCAL variable is one of the standard set of variables available to CGI programs, which SSI can also access. (See http://www.georgedillon.com/web/ssivar.shtml for a useful list of variables.) Additionally, you could output the last date modified, as in Listing 10.
Listing 10
Adding the Last Date Modified
The default date format is a full date with the time, as shown in Figure 2. You can also set the time/date format before you echo the time. For example, the code shown in Listing 11 would output just the date with the format: Tue 28 Jul, 2009.
Listing 11
Formatting the Date
Finally, you can use includes to run a CGI program, or any other code, and output the result. For example, the code in Listing 12 produces a directory listing.
Note that Listing 12 is a big security risk! Because you can execute any arbitrary code within that exec block, if you allow SSIs on a page in which users can edit content (a wiki page or a page with comments of some sort turned on), an attacker could do many bad things. To turn this feature off, set the Options directive –
Options +IncludesNOEXEC
– just to be safe.
Listing 12
A Directory Listing in Your Page
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Halcyon Creates Anti-Ransomware Protection for Linux
As more Linux systems are targeted by ransomware, Halcyon is stepping up its protection.
-
Valve and Arch Linux Announce Collaboration
Valve and Arch have come together for two projects that will have a serious impact on the Linux distribution.
-
Hacker Successfully Runs Linux on a CPU from the Early ‘70s
From the office of "Look what I can do," Dmitry Grinberg was able to get Linux running on a processor that was created in 1971.
-
OSI and LPI Form Strategic Alliance
With a goal of strengthening Linux and open source communities, this new alliance aims to nurture the growth of more highly skilled professionals.
-
Fedora 41 Beta Available with Some Interesting Additions
If you're a Fedora fan, you'll be excited to hear the beta version of the latest release is now available for testing and includes plenty of updates.
-
AlmaLinux Unveils New Hardware Certification Process
The AlmaLinux Hardware Certification Program run by the Certification Special Interest Group (SIG) aims to ensure seamless compatibility between AlmaLinux and a wide range of hardware configurations.
-
Wind River Introduces eLxr Pro Linux Solution
eLxr Pro offers an end-to-end Linux solution backed by expert commercial support.
-
Juno Tab 3 Launches with Ubuntu 24.04
Anyone looking for a full-blown Linux tablet need look no further. Juno has released the Tab 3.
-
New KDE Slimbook Plasma Available for Preorder
Powered by an AMD Ryzen CPU, the latest KDE Slimbook laptop is powerful enough for local AI tasks.
-
Rhino Linux Announces Latest "Quick Update"
If you prefer your Linux distribution to be of the rolling type, Rhino Linux delivers a beautiful and reliable experience.