home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


CONTENTS

Chapter 7. Indexing

As we saw back on site.first (see Chapter 3), if there is no index.html file in ... /htdocs or DirectoryIndex directive, Apache concocts an index called "Index of /", where "/" means the DocumentRoot directory. For many purposes this will, no doubt, be enough. But since this jury-rigged index is the first thing a client sees, you may want to do more.

7.1 Making Better Indexes in Apache

There is a wide range of possibilities; some are demonstrated at ... /site.fancyindex /httpd1.conf:

User webuser
Group webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/APACHE3/site.fancyindex/htdocs

<Directory /usr/www/APACHE3/site.fancyindex/htdocs>
IndexOptions FancyIndexing
AddDescription "One of our wonderful catalogs" catalog_summer.html /
    catalog_autumn.html
IndexIgnore *.jpg
IndexIgnore  ..
IndexIgnore  icons HEADER README
AddIconByType (CAT,icons/bomb.gif) text/*
DefaultIcon icons/burst.gif
</Directory>

When you type ./go 1 on the server and access http://www.butterthlies.com/ on the browser, you should see a rather fancy display:

Index of /
  Name                        Last Modified     Size Description 
--------------------------------------------------------------------
    <bomb>catalog_autumn.html 23-Jul-1998 09:11 1k   One of our wonderful catalogs 
    <bomb>catalog_summer.html 25-Jul-1998 10:31 1k   One of our wonderful catalogs 
    <burst>index.html.ok      23-Jul-1998 09:11 1k 
-------------------------------------------------------------------- 

In the previous listing, <bomb> and <burst> stand in for standard graphic icons Apache has at its disposal. How does all this work? As you can see from the httpd.conf file, this smart formatting is displayed directory by directory. The key directive is IndexOptions.

IndexOptions  

IndexOptions option [option] ... (Apache 1.3.2 and earlier)
IndexOptions [+|-]option [[+|-]option] ... (Apache 1.3.3 and later) 
Server config, virtual host, directory, .htaccess
 

This directive is somewhat complicated, and its syntax varies drastically depending on your version of Apache.

+/- syntax and merging of multiple IndexOptions directives is only available with Apache 1.3.3 and later; the FoldersFirst and DescriptionWidth options are only available with Apache 1.3.10 and later; the TrackModified option is only available with Apache 1.3.15 and later.

The IndexOptions directive specifies the behavior of the directory indexing. option can be one of the following:

DescriptionWidth=[n | *] (Apache 1.3.10 and later)

The DescriptionWidth keyword allows you to specify the width of the description column in characters. If the keyword value is *, then the column is automatically sized to the length of the longest filename in the display. See AddDescription for dangers inherent in truncating descriptions.

FancyIndexing

This turns on fancy indexing, which gives users more control over how the information is sorted.

Note that in versions of Apache prior to 1.3.2, the FancyIndexing and IndexOptions directives will override each other. You should use IndexOptions FancyIndexing in preference to the standalone FancyIndexing directive. As of Apache 1.3.2, a standalone FancyIndexing directive is combined with any IndexOptions directive already specified for the current scope.

FoldersFirst (Apache 1.3.10 and later)

If this option is enabled, subdirectories in a FancyIndexed listing will always appear first, followed by normal files in the directory. The listing is basically broken into two components, the files and the subdirectories, and each is sorted separately and then displayed with the subdirectories first. For instance, if the sort order is descending by name, and FoldersFirst is enabled, subdirectory Zed will be listed before subdirectory Beta, which will be listed before normal files Gamma and Alpha. This option only has an effect if FancyIndexing is also enabled.

IconHeight[=pixels] (Apache 1.3 and later)IconWidth[=pixels] (Apache 1.3 and later)

If these two options are used together, the server will include HEIGHT and WIDTH attributes in the IMG HTML tag for the file icon. This allows the browser to precalculate the page layout without waiting for all the images to load. If no value is given for the option, it defaults to the standard height of the icons supplied with the Apache software.

IconsAreLinks

This makes the icons part of the anchor for the filename for fancy indexing.

NameWidth=[n | *] (Apache 1.3.2 and later)

The NameWidth keyword allows you to specify the width of the filename column in bytes. If the keyword value is *, then the column is automatically sized to the length of the longest filename in the display.

ScanHTMLTitles

This enables the extraction of the title from HTML documents for fancy indexing. If the file does not have a description given by AddDescription, then httpd will read the document for the value of the TITLE tag. This is CPU and disk intensive.

SuppressColumnSorting

If specified, Apache will not make the column headings in a FancyIndexed directory listing into links for sorting. The default behavior is for them to be links; selecting the column heading will sort the directory listing by the values in that column. Only available in Apache 1.3 and later.

SuppressDescription

This will suppress the file description in fancy-indexing listings.

SuppressHTMLPreamble (Apache 1.3 and later)

If the directory actually contains a file specified by the HeaderName directive, the module usually includes the contents of the file after a standard HTML preamble (<HTML>, <HEAD>, etc.). The SuppressHTMLPreamble option disables this behavior, causing the module to start the display with the header-file contents. The header file must contain appropriate HTML instructions in this case. If there is no header file, the preamble is generated as usual.

SuppressLastModified

This will suppress the display of the last modification date in fancy-indexing listings.

SuppressSize

This will suppress the file size in fancy-indexing listings.

TrackModified (Apache 1.3.15 and later)

This returns the Last-Modified and ETag values for the directory listed in the HTTP header. It is only valid if the operating system and filesystem return legitimate stat( ) results. Most Unix systems do so, as do OS/2's JFS and Win32's NTFS volumes. OS/2 and Win32 FAT volumes, for example, do not. Once this feature is enabled, the client or proxy can track changes to the list of files when they perform a HEAD request. Note some operating systems correctly track new and removed files, but do not track changes for sizes or dates of the files within the directory.

There are some noticeable differences in the behavior of this directive in recent (post-1.3.0) versions of Apache.

For Apache 1.3.2 and Earlier

The default is that no options are enabled. If multiple IndexOptions could apply to a directory, then the most specific one is taken complete; the options are not merged. For example:

<Directory /web/docs>
    IndexOptions FancyIndexing
</Directory>
<Directory /web/docs/spec>
    IndexOptions ScanHTMLTitles
</Directory>

In this case, only ScanHTMLTitles will be set for the /web/docs/spec directory.

For Apache 1.3.3 and Later

Apache 1.3.3 introduced some significant changes in the handling of IndexOptions directives. In particular:

  • Multiple IndexOptions directives for a single directory are now merged together. The result of the previous example will now be the equivalent of IndexOptions FancyIndexing ScanHTMLTitles.

  • The addition of the incremental syntax (i.e., prefixing keywords with + or -). Whenever a + or - prefixed keyword is encountered, it is applied to the current IndexOptions settings (which may have been inherited from an upper-level directory). However, whenever an unprefixed keyword is processed, it clears all inherited options and any incremental settings encountered so far. Consider the following example:

    	IndexOptions +ScanHTMLTitles -IconsAreLinks FancyIndexing
    	IndexOptions +SuppressSize 

    The net effect is equivalent to IndexOptions FancyIndexing +SuppressSize, because the unprefixed FancyIndexing discarded the incremental keywords before it, but allowed them to start accumulating again afterward.

    To set the IndexOptions unconditionally for a particular directory — clearing the inherited settings — specify keywords without either + or - prefixes.

IndexOrderDefault  

IndexOrderDefault Ascending|Descending Name|Date|Size|Description 
Server config, virtual host, directory, .htaccess 
IndexOrderDefault is only available in Apache 1.3.4 and later. 
 

The IndexOrderDefault directive is used in combination with the FancyIndexing index option. By default, FancyIndexed directory listings are displayed in ascending order by filename; IndexOrderDefault allows you to change this initial display order.

IndexOrderDefault takes two arguments. The first must be either Ascending or Descending, indicating the direction of the sort. The second argument must be one of the keywords Name, Date, Size, or Description and identifies the primary key. The secondary key is always the ascending filename.

You can force a directory listing to be displayed only in a particular order by combining this directive with the SuppressColumnSorting index option; this will prevent the client from requesting the directory listing in a different order.

ReadmeName  

ReadmeName filename
Server config, virtual host, directory, .htaccess
Some features only available after 1.3.6; see text 
 

The ReadmeName directive sets the name of the file that will be appended to the end of the index listing. filename is the name of the file to include and is taken to be relative to the location being indexed.

The filename argument is treated as a stub filename in Apache 1.3.6 and earlier, and as a relative URI in later versions. Details of how it is handled may be found under the description of the HeaderName directive, which uses the same mechanism and changed at the same time as ReadmeName.

See also HeaderName.

FancyIndexing  

FancyIndexing on_or_off
Server config, virtual host, directory, .htaccess
 

FancyIndexing turns fancy indexing on. The user can click on a column title to sort the entries by value. Clicking again will reverse the sort. Sorting can be turned off with the SuppressColumnSorting keyword for IndexOptions (see earlier in this chapter). See also the FancyIndexing option for IndexOptions.

IndexIgnore  

IndexIgnore file1 file2 ...
Server config, virtual host, directory, .htaccess
 

We can specify a description for individual files or for a list of them. We can exclude files from the listing with IndexIgnore.

IndexIgnore is followed by a list of files or wildcards to describe files. As we see in the following example, multiple IndexIgnores add to the list rather than replacing each other. By default, the list includes ".".

You might well want to ignore .ht* files so that the Bad Guys can't look at the actual .htaccess files. Here we want to ignore the *.jpg files (which are not much use without the .html files that display them and explain what they show) and the parent directory, known to Unix and to Win32 as "..":

...
<Directory /usr/www/APAC
HE3/fancyindex.txt/htdocs>
FancyIndexing on
AddDescription "One of our wonderful catalogs" catalog_autumn.html catalog_summer.html
IndexIgnore *.jpg ..
</Directory>

You might want to use IndexIgnore for security reasons as well: what the eye doesn't see, the mouse finger can't steal.[1] You can put in extra IndexIgnore lines, and the effects are cumulative, so we could just as well write:

<Directory /usr/www/APACHE3/fancyindex.txt/htdocs>
FancyIndexing on
AddDescription "One of our wonderful catalogs" catalog_autumn.html catalog_summer.html
IndexIgnore *.jpg
IndexIgnore ..
</Directory>
AddIcon  

AddIcon icon_name name
Server config, virtual host, directory, .htaccess
 

We can add visual sparkle to our page by giving icons to the files with the AddIcon directive. Apache has more icons than you can shake a stick at in its ... /icons directory. Without spending some time exploring, one doesn't know precisely what each one looks like, but bomb.gif will do for an example. The icons directory needs to be specified relative to the DocumentRoot directory, so we have made a subdirectory ... /htdocs/icons and copied bomb.gif into it. We can attach the bomb icon to all displayed .html files with this:

...
AddIcon icons/bomb.gif  .html

AddIcon expects the URL of an icon, followed by a file extension, wildcard expression, partial filename, or complete filename to describe the files to which the icon will be added. We can iconify subdirectories off the DocumentRoot with ^^DIRECTORY^^, or make blank lines format properly with ^^BLANKICON^^. Since we have the convenient icons directory to practice with, we can iconify it with this:

AddIcon /icons/burst.gif ^^DIRECTORY^^

Or we can make it disappear with this:

...
IndexIgnore  icons
...

Not all browsers can display icons. We can cater to those that cannot by providing a text alternative alongside the icon URL:

AddIcon ("DIR",/icons/burst.gif) ^^DIRECTORY^^

This line will print the word DIR where the burst icon would have appeared to mark a directory (that is, the text is used as the ALT description in the link to the icon). You could, if you wanted, print the word "Directory" or "This is a directory." The choice is yours.

Here are several examples of uses of AddIcon:

AddIcon (IMG,/icons/image.xbm) .gif .jpg .xbm 
AddIcon /icons/dir.xbm ^^DIRECTORY^^ 
AddIcon /icons/backup.xbm *~ 

AddIconByType should be used in preference to AddIcon, when possible.

AddAlt  

AddAlt string file file ...
Server config, virtual host, directory, .htaccess
 

AddAlt sets alternate text to display for the file if the client's browser can't display an icon. The stringmust be enclosed in double quotes.

AddDescription  

AddDescription string file1 file2 ...
Server config, virtual host, directory, .htaccess
 

AddDescription expects a description string in double quotes, followed by a file extension, partial filename, wildcards, or full filename:

<Directory /usr/www/APACHE3/fancyindex.txt/htdocs>
FancyIndexing on
AddDescription "One of our wonderful catalogs" catalog_autumn.html 
    catalog_summer.html
IndexIgnore *.jpg
IndexIgnore ..
AddIcon (CAT,icons/bomb.gif)  .html
AddIcon (DIR,icons/burst.gif) ^^DIRECTORY^^
AddIcon icons/blank.gif ^^BLANKICON^^
DefaultIcon icons/blank.gif
</Directory>

Having achieved these wonders, we might now want to be a bit more sensible and choose our icons by MIME type using the AddIconByType directive.

DefaultIcon  

DefaultIcon url
Server config, virtual host, directory, .htaccess
 

DefaultIcon sets a default icon to display for unknown file types. url is relative and points to the icon.

AddIconByType  

AddIconByType icon mime_type1 mime_type2 ...
Server config, virtual host, directory, .htaccess
 

AddIconByType takes an icon URL as an argument, followed by a list of MIME types. Apache looks for the type entry in mime.types, either with or without a wildcard. We have the following MIME types:

...
text/html html htm
text/plain text
text/richtext rtx
text/tab-separated-values tsv
text/x-setext text
...

So, we could have one icon for all text files by including the line:

AddIconByType (TXT,icons/bomb.gif) text/*

Or we could be more specific, using four icons, a.gif, b.gif, c.gif, and d.gif :

AddIconByType (TXT,/icons/a.gif) text/html
AddIconByType (TXT,/icons/b.gif) text/plain
AddIconByType (TXT,/icons/c.gif) text/tab-separated-values
AddIconByType (TXT,/icons/d.gif) text/x-setext

Let's try out the simpler case:

<Directory /usr/www/APACHE3/fancyindex.txt/htdocs>
FancyIndexing on
AddDescription "One of our wonderful catalogs" catalog_autumn.html 
    catalog_summer.html
IndexIgnore *.jpg
IndexIgnore ..
AddIconByType (CAT,icons/bomb.gif)  text/*
AddIcon (DIR,icons/burst.gif) ^^DIRECTORY^^
</Directory>

For a further refinement, we can use AddIconByEncoding to give a special icon to encoded files.

AddAltByType  

AddAltByType string mime_type1 mime_type2 ...
Server config, virtual host, directory, .htaccess
 

AddAltByType provides a text string for the browser to display if it cannot show an icon. The string must be enclosed in double quotes.

AddIconByEncoding  

AddIconByEncoding icon mime_encoding1 >mime_encoding2 ...
Server config, virtual host, directory, .htaccess
 

AddIconByEncoding takes an icon name followed by a list of MIME encodings. For instance, x-compress files can be iconified with the following:

...
AddIconByEncoding (COMP,/icons/d.gif) application/x-compress
...
AddAltByEncoding  

AddAltByEncoding string mime_encoding1 mime_encoding2 ...
Server config, virtual host, directory, .htaccess
 

AddAltByEncoding provides a text string for the browser to display if it can't put up an icon. The string must be enclosed in double quotes.

Next, in our relentless drive for perfection, we can print standard headers and footers to our directory listings with the HeaderName and ReadmeName directives.

HeaderName  

HeaderName filename
Server config, virtual host, directory, .htaccess
 

This directive inserts a header, read from filename, at the top of the index. The name of the file is taken to be relative to the directory being indexed. Apache will look first for filename.html and, if that is not found, then filename.

Apache Versions After 1.3.6

filename is treated as a URI path relative to the one used to access the directory being indexed and must resolve to a document with a major content type of "text" (e.g., text/html, text/plain, etc.). This means that filename may refer to a CGI script if the script's actual file type (as opposed to its output) is marked as text/html, such as with the following directive:

AddType text/html .cgi

Content negotiation will be performed if the MultiViews option is enabled. If filename resolves to a static text/html document (not a CGI script) and the Includes option is enabled, the file will be processed for server-side includes (see the mod_include documentation).

If the file specified by HeaderName contains the beginnings of an HTML document (<HTML>, <HEAD>, etc.), then you will probably want to set IndexOptions +SuppressHTMLPreamble, so that these tags are not repeated. (See also ReadmeName.)

<Directory /usr/www/APACHE3/fancyindex.txt/htdocs>
FancyIndexing on
AddDescription "One of our wonderful catalogs"
catalog_autumn.html catalog_summer.html
IndexIgnore *.jpg
IndexIgnore .. icons HEADER README
AddIconByType (CAT,icons/bomb.gif)  text/*
AddIcon (DIR,icons/burst.gif) ^^DIRECTORY^^
HeaderName HEADER
ReadMeName README
</Directory>

Since HEADER and README can be HTML documents, you can wrap the directory listing up in a whole lot of fancy interactive stuff if you want.

On the whole, however, FancyIndexing is just a cheap and cheerful way of getting something up on the Web. For a more elegant solution, study the next section.

7.2 Making Our Own Indexes

In the last section, we looked at Apache's indexing facilities. So far we have not been very adventurous with our own indexing of the document root directory. We replaced Apache's adequate directory listing with a custom-made .html file: index.html (see Chapter 3).

We can improve on index.html with the DirectoryIndex command. This command specifies a list of possible index files to be used in order.

7.2.1 DirectoryIndex

The DirectoryIndex directive sets the list of resources to look for when the client requests an index of the directory by specifying a / at the end of the directory name.

DirectoryIndex local-url local-url ...
Default: index.html
Server config, virtual host, directory, .htaccess

local-url is the URL of a document on the server relative to the requested directory; it is usually the name of a file in the directory. Several URLs may be given, in which case the server will return the first one that it finds. If none of the resources exists and IndexOptions is set, the server will generate its own listing of the directory. For example, if this is the specification:

DirectoryIndex index.html 

then a request for http://myserver/docs/ would return http://myserver/docs/index.html if it did not exist; if it exists, the request would list the directory, provided indexing was allowed. Note that the documents do not need to be relative to the directory:

DirectoryIndex index.html index.txt /cgi-bin/index.pl

This would cause the CGI script /cgi-bin/index.pl to be executed if neither index.html nor index.txt existed in a directory.

A common technique for getting a CGI script to run immediately when a site is accessed is to declare it as the DirectoryIndex:

DirectoryIndex /cgi-bin/my_start_script

If this is to work, redirection to cgi-bin must have been arranged using ScriptAlias or ScriptAliasMatch higher up in the Config file.

The Config file from ... /site.ownindex is as follows:

User webuser
Group webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/APACHE3/site.ownindex/htdocs
AddHandler cgi-script cgi
Options ExecCGI indexes

<Directory /usr/www/APACHE3/site.ownindex/htdocs/d1>
DirectoryIndex hullo.cgi index.html goodbye
</Directory>

<Directory /usr/www/APACHE3/site.ownindex/htdocs/d2>
DirectoryIndex index.html goodbye
</Directory>

<Directory /usr/www/APACHE3/site.ownindex/htdocs/d3>
DirectoryIndex goodbye
</Directory>

In ... /htdocs we have five subdirectories, each containing what you would expect to find in ... /htdocs itself, plus the following files:

  • hullo.cgi

  • index.html

  • goodbye

The CGI script hullo.cgi contains:

#!/bin/sh
echo "Content-type: text/html"
echo
env
echo Hi there

The HTML document index.html contains:

<!DOCTYPE HTML PUBLIC "//-W3C//DTD HTML 4.0//EN"
<html>
<head>
<title>Index to Butterthlies Catalogues</title>
</head>
<body>
<h1>Index to Butterthlies Catalogues</h1>
<ul>
<li><A href="catalog_summer.html">Summer catalog </A>
<li><A href="catalog_autumn.html">Autumn catalog </A>
</ul>
<hr>
<br>
Butterthlies Inc, Hopeful City, Nevada,000 111 222 3333
</br>
</body>
</html>

The text file goodbye is:

Sorry, we can't help you. Have a nice day!

The Config file sets up different DirectoryIndex options for each subdirectory with a decreasing list of DirectoryIndexes. If hullo.cgi fails for any reason, then index.html is used, if that fails, we have a polite message in goodbye.

In real life, hullo.cgi might be a very energetic script that really got to work on the clients — registering their account numbers, encouraging the free spenders, chiding the close-fisted, and generally promoting healthy commerce. Actually, we won't go to all that trouble just now. We will just copy the file /usr/www/APACHE3/cgi-bin/mycgi to ... /htdocs/d*/hullo.cgi.

figs/unix.gif

If you are using Unix and hullo.cgi isn't executable, remember to make it executable in its new home with the following:

chmod +x hullo.cgi

Start Apache with ./go, and access www.butterthlies.com. You see the following:

Index of /

. Parent Directory
. d1
. d2
. d3
. d4
. d5

If we select d1, we get:

GATEWAY_INTERFACE=CGI/1.1 
REMOTE_ADDR=192.168.123.1 
QUERY_STRING= 
REMOTE_PORT=1080 
HTTP_USER_AGENT=Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt) 
DOCUMENT_ROOT=/usr/www/APACHE3/site.ownindex/htdocs 
SERVER_SIGNATURE= 
HTTP_ACCEPT=image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-
excel, application/msword, application/vnd.ms-powerpoint, */* 
SCRIPT_FILENAME=/usr/www/APACHE3/site.ownindex/htdocs/d1/hullo.cgi 
HTTP_HOST=www.butterthlies.com 
REQUEST_URI=/d1/ 
SERVER_SOFTWARE=Apache/1.3.14 (Unix) 
HTTP_CONNECTION=Keep-Alive 
REDIRECT_URL=/d1/ 
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/usr/
X11R6/bin:/root/bin:/usr/src/java/jdk1.1.8/bin 
HTTP_ACCEPT_LANGUAGE=en-gb 
HTTP_REFERER=http://www.butterthlies.com/ SERVER_PROTOCOL=HTTP/1.1 
HTTP_ACCEPT_ENCODING=gzip, deflate REDIRECT_STATUS=200 
REQUEST_METHOD=GET 
SERVER_ADMIN=[no address given] 
SERVER_ADDR=192.168.123.2 
SERVER_PORT=80 
SCRIPT_NAME=/d1/hullo.cgi 
SERVER_NAME=www.butterthlies.com
have a nice day 

If we select d2 (or disable ... /d1/hullo.cgi), we should see the output of ... /htdocs/d1/index.html:

D2: Index to Butterthlies Catalogs

* catalog_summer.html
* catalog_autumn.html

Butterthlies Inc, Hopeful City, Nevada 99999

If we select d3, we get this:

Sorry, we can't help you. Have a nice day!

If we select d4, we get this:

Index of /d4 
. Parent Directory 
. bath.jpg 
. bench.jpg 
. catalog_autumn.html 
. catalog_summer.html 
. hen.jpg 
. tree.jpg

In directory d5, we have the contents of d1, plus a .htaccess file that contains:

DirectoryIndex hullo.cgi index.html goodbye

This gives us the same three possibilities as before. It's worth remembering that using entries in .htaccess is much slower than using entries in the Config file. This is because the directives in the ... /conf files are loaded when Apache starts, whereas .htaccess is consulted each time a client accesses the site.

Generally, the DirectoryIndex method leaves the ball in your court. You have to write the index.html scripts to do whatever needs to be done, but of course, you have the opportunity to produce something amazing.

7.3 Imagemaps

We have experimented with various sorts of indexing. Bearing in mind that words are going out of fashion in many circles, we may want to present an index as some sort of picture. In some circumstances, two dimensions may work much better than one; selecting places from a map, for instance, is a natural example. The objective here is to let the client user click on images or areas of images and to deduce from the position of the cursor at the time of the click what she wants to do next.

Recently, browsers have improved in capability, and client-side mapping (built into the returned HTML document) is becoming more popular. If you want to use server-side image maps, however, Apache provides support. The httpd.conf in ... /site.imap is as follows:

User webuser
Group webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/APACHE3/site.imap/htdocs

AddHandler imap-file map
ImapBase map
ImapMenu Formatted

The three lines of note are the last. AddHandler sets up ImageMap handling using files with the extension .map. When you access the site you see the following:

Index of /
		Parent Directory 
	bench.jpg 
	bench.map 
	bench.map.bak 
	default.html 
	left.html 
	right.html 
	sides.html 
	things 

This index could be made simpler and more elegant by using some of the directives mentioned earlier. In the interest of keeping the Config file simple, we leave this as an exercise for the reader.

Click on sides.html to see the action. The picture of the bench is presented: if you click on the left you see this:

Index of /things
		Parent Directory 
	1 
	2 
	3 

If you click on the righthand side, you see:

you like to sit on the right 

If you click outside one of the defined areas (as in ... /htdocs/sides.html), you see:

You're clicking in the wrong place 

7.3.1 HTML File

The document we serve up is ... /htdocs/sides.html:

<!DOCTYPE HTML PUBLIC "//-W3C//DTD HTML 4.0//EN"
<html>
<head>
<title>Index to Butterthlies Catalogues</title>
</head>
<body>
<h1>Welcome to Butterthlies Inc</h1>
<h2>Which Side of the Bench?</h2>
<p>Tell us on which side of the bench you like to sit
</p>
<hr>
<p>
<p align=center>
<a href="bench.map">
<img ismap src="bench.jpg" alt="A picture of a bench">
</a>
<p align=center>
Click on the side you prefer
</body>
</html>

This displays the now-familiar picture of the bench and asks you to indicate which side you prefer by clicking on it. You must include the ismap attribute in the <IMG> element to activate this behavior. Apache's ImageMap handler then refers to the file .../site.imap/htdocs/bench.map to make sense of the mouse-click coordinates.

7.3.2 Map File

It finds the following lines in the file .../site.imap/htdocs/bench.map:

rect left.html 0,0 118,144
rect right.html 118,0 237,144

#point left.html 59,72
#point right.html 177,72

#poly left.html 0,0 118,0 118,144 0,144
#poly things 0,0 118,0 118,144 0,144
#poly right.html 118,0 237,0 237,144 118,114

#circle left.html 59,72 118,72
#circle things 59,72 118,72
#circle right.html 177,72 237,72

default default.html

The coordinates start from 0,0, the top-lefthand corner of the image. rects are rectangles with the top-left and bottom-right corners at the two x,y positions shown. points are points at the x,y position. polys are polygons with between 3 and 100 corners at the x,ys shown. circles have their center at the first x,y — the second is a point on the circle. The point nearest to the cursor is returned; otherwise, the closed figure that encloses the cursor is not returned. As it stands only the rects are left uncommented. They set up two areas in the left and right halves of the image and designate the files left.html and right.html to be returned if the mouse click occurs in the corresponding rectangle. Notice that the points are expressed as x,y <whitespace>. If you click in the left rectangle, the URL www.butterthlies.com/left.html is accessed, and you see the message:

You like to sit on the left

and conversely for clicks on the right side. In a real application, these files would be menus leading in different directions; here they are simple text files:

You like to sit on the left
You like to sit on the right

In a real system, you might now want to display the contents of another directory, rather than the contents of a file (which might be an HTML document that itself is a menu). To demonstrate this, we have a directory, ... /htdocs/things, which contains the rubbish files 1, 2, 3. If we replace left.html in bench.map with things, as follows:

rect things 0,0 118,144
rect right.html 118,0 237,144

we see:

Index of /things
. Parent Directory
. 1
. 2
. 3

You do not have to restart Apache when you change bench.map, and the formatting of this menu is not affected by the setting for IMapMenu.

How do we know what the coordinates of the rectangles are (for instance, 0,0 118,144)? If we access sides.html and put the cursor on the picture of the bench, Netscape/MSIE helpfully prints its coordinates on the screen — following the URL and displayed in a little window at the bottom of the frame. For instance:

http://192.168.123.2/bench.map?98,125

It is quite easy to miss this if the Netscape window is too narrow or stretches off the bottom of the screen. We can then jot down on a bit of paper that the picture runs from 0,0 at the top-left corner to 237,144 at the bottom-right. Half of 237 is 118.5, so 118 will do as the dividing line.

We divided the image of the bench into two rectangles:

0,0 118,144
118,0 237,144

These are the center points of these two rectangles:

59,72
177,72

so we can rewrite bench.map as:

point left.html 59,72
point right.html 177,72

and get the same effect.

The version of bench.map for polygons looks like this:

poly left.html 0,0 118,0 118,144 0,144
poly right.html 118,0 237,0 237,144 118,114

For circles, we use these points as centers and add 118/2=59 to the x-coordinates for the radius. This should give us two circles in which the cursor is detected and the rest of the picture (right in the corners, for instance) in which it is not:

circle left.html 59,72 118,72
circle right.html 177,72 237,72

When things go wrong with ImageMaps — which we can engineer by setting circlesin bench.map and clicking on the corners of the picture — the action to take is set first by a line in the file bench.map :

default [error|nocontent|map|referer|URL]

The meanings of the arguments are given under the ImapDefaultabove. If this line is not present, then the directive ImapDefault takes over. In this case we set:

default default.html

and the file default.html is displayed, which says:

You are clicking in the wrong place.

7.4 Image Map Directives

The three image map directives let you specify how Apache handles serverside image maps.

ImapBase  

ImapBase [map|referer|URL]
Default: http://servername
Server config, virtual host, directory, .htaccess 
 

This directive sets the base URL for the ImageMap, as follows:

map

The URL of the ImageMap itself.

referer

The URL of the referring document. If this is unknown, http://servername/ is used.

URL

The specified URL.

If this directive is absent, the map base defaults to http://servername/, which is the same as the DocumentRoot directory.

ImapMenu  

ImapMenu [none|formatted|semiformatted|unformatted]
Server config, virtual host, directory, .htaccess
Default: formatted
 

This directive applies if mapping fails or if the browser is incapable of displaying images. If the site is accessed using a text-based browser such as Lynx, a menu is displayed showing the possibilities in the .map file:

MENU FOR /BENCH.MAP
--------------------------------------
       things
       right.html

This is formatted according to the argument given to ImapMenu. The previous effect is produced by formatted. The manual explains the options as follows:

formatted

A formatted menu is the simplest menu. Comments in the ImageMap file are ignored. A level-one header is printed, then a horizontal rule, and then the links, each on a separate line. The menu has a consistent, plain look close to that of a directory listing.

semiformatted

In the semiformatted menu, comments are printed where they occur in the ImageMap file. Blank lines are turned into HTML breaks. No header or horizontal rule is printed, but otherwise the menu is the same as a formatted menu.

unformatted

Comments are printed; blank lines are ignored. Nothing is printed that does not appear in the ImageMap file. All breaks and headers must be included as comments in the ImageMap file. This gives you the most flexibility over the appearance of your menus, but requires you to treat your map files as HTML instead of plain text.

The argument none redisplays the document sides.html.

ImapDefault  

ImapDefault [error|nocontent|map|URL]
Default: nocontent
Server config, virtual host, directory, .htaccess 
 

There is a choice of actions (if you spell them incorrectly, no error message appears and no action results):

error

This makes Apache serve up a standard error message, which appears on the browser (depending on which one it is) as something like "Internal Server Error."

nocontent

Apache ignores the request.

map

Apache returns the message Document moved here.

URL

Apache returns the URL. If it is relative, then it will be relative to the ImageMap base. On this site we serve up the file default.html to deal with errors. It contains the message:

You're clicking in the wrong place

[1]  While you should never rely solely on security by obscurity, it doesn't hurt, and it can be a useful supplement.

CONTENTS