The WN server has powerful capabilities for modifying a text file as it is served. One such feature, called "server-side includes", is the ability to automatically insert one file in another. But the usefulness of this capability is greatly enhanced by another feature, conditional text. A simple if - else - endif construct allows sections of a document to be served only to certain hosts, or to clients providing an appropriate Accept header or a desired Referer or User-Agent header. Using the "else" construct allows alternate text segments for clients not meeting the desired criteria. For these features to work it is necessary for the server to parse the file looking for the location of includes or for conditionally served text. The fact that a file should be parsed in this way is indicated in its entry in its index file. This is done with an entry "Attributes=parse" in the file record. See the section concerning attributes in Appendix B. (This line is not neccessary if the file record lists wrappers or includes since it is assumed in that case.)
To ensure security various options are available including the the requirement that a served file and all its includes and wrappers have the same owner as the index.cache file listing them. This is done with the -u option.
Another important application of wrappers is to customize the HTML documents returned listing the successful search matches. If, for example, a directory is assigned a wrapper the server assumes that it contains all text describing the search and it merely supplies an unordered list of links to the matching items.
File=foo.html
Includes=bar.html
and the file foo.html should contain either of the lines
<!-- #include -->
or
<?WN #include >
These two forms are equivalent as far as the server is concerned. The second form is considered more SGML friendly by many as <?WN something > indicates a processing instruction specific to WN rather than a comment. For historical reasons this manual describes the other form, but either may be used. With the first form the '#' is required but with the other you may use either
<?WN #include > or
<?WN include >
Any of the "<!-- #something -->" lines described in this section may be replaced using the "<?WN" syntax. Also with this syntax the case of the WN is not significant.
The marker <!-- #include --> should be the only thing on its line but may have white space before it. This is controlled by the Includes= line in the index file. All including of files by WN is done only for text files and only in units of lines.
If the include marker is never found in foo.html, then this file is served and the file bar.html, is appended at the end. Thus the Includes= directive can be used to append a file without the need of any marker in the main file.
If you wanted to include two files in foo.html, say bar.html and bah.html you would place the marker <!-- #include --> at two places in foo.html and have an entry in your index file like
File=foo.html
Includes=bar.html,bah.html
The two files will then be included at the marked spots in the order that they are listed in the Includes= directive, i.e. bar.html will be inserted at the first marker and bah.html at the second. You can have as many included files as you wish. They should all be listed on the "Includes=" line separated by commas.
Sometimes it is easier to specify the order in which multiple files are to be inserted by adding the file name in the HTML document. This is also possible with WN. However, since good security requires that only files listed in the index file may be served, it is still necessary to list files you want to include there. So, another way to include two files in foo.html, say, bar and bah, is to place the markers <!-- #include "bar" --> and <!-- #include "bah" --> at the appropriate places in foo.html and have an entry in your index file like
File=foo.html
List-Includes=bar,bah
The order of the files listed in the directive is not significant. The example above grants permission for the inclusion of the three files listed. It does not require their insertion. Note the difference between the two mechanisms: with the Includes directive only <!-- #include --> is needed in the HTML and the file inserted is taken (in order) from the list in the directive, while with the List-Includes directive the HTML must contain <!-- #include "bah" --> so the server knows to insert file "bah" and the file list in the directive is checked to see that permission to serve this file has been granted. If you use the List-Includes directive you cannot also use either the Includes or Wrappers directives -- the List-Includes and Includes/Wrappers mechanisms are mutually exclusive. It is fine to use the line <!-- #include bar.html --> to insert a file with the Includes directive, but with that directive the "bar.html" is only a comment and has no effect on which file is actually inserted.
There is a Default-List-Includes directory directive which can be used to grant permission for any HTML file in the directory to include one or more of the listed files. This also causes all HTML files in the directory to acquire the parse attribute.
If a file has a filter only that file will be filtered, not any wrappers or includes.
Instead of a file it is possible to include the output of a program or script. To do this the program is listed in the Includes= directive but its name is preceded with the '!' character. For example
File=foo.html Includes=!/usr/bin/date -u,bar.htmlwill insert the time and date (GMT) at the first <!-- #include --> and the contents of bar.html at the second. This ability to serve the output of programs can be restricted in several ways. If WN is invoked with the -e option then no includes, filters, or CGI programs will be executed.
The -E option in conjunction with the -t or -T options restricts the execution of programs to those listed in index.cache files owned by trusted users or groups. The -u option allows the execution of programs or inclusion of files owned by the owner of the index.cache file which lists them. If the -E and -u option are used together the -E takes precedence.
If you wish to have all the standard CGI environment variables made available to the executed include program you can do so by adding the line
Attributes=CGIto the file record. A list of these environment variables can be found in the Appendix D. (Also see the sample CGI script which is located in the file /docs/examples/sample.cgi which accompainies the WN distribution.)
<!-- #if accept =~ "image/jpeg" -->This tells the server to look at the Accept: headers provided by the client and if "image/jpeg" is among them then use the jpeg image and otherwise use the gif image. More precisely, the "image/jpeg" part of the "if" line is a grep-like regular expression and if there is any match for it among the Accept headers the jpeg image will be used. Of course these if - else - endif constructs can be nested. A similar construct allows you to make the text served depend on matching a regular expression with the contents of the User-Agent header, the Referer header, the Cookie header, the client hostname, or the client IP address. A complete list of possible test clauses for the #if statement is contained in Appendix C.
<a href="picture.jpg">
Here is the jpeg version of the picture:
</a>
<!-- #else -->
<a href="picture.gif">
Here is the gif version of the picture:
</a>
<!-- #endif -->
Important: For this to work the file containing the conditional text needs to be parsed by the server. The server only knows to do this if the file record in the index file contains a line "Attributes=parse". See the section concerning attributes in Appendix B for full details.
If, in an "if clause", instead of the equal-tilde string =~ (to indicate a regular expression match) the character string !~ is used then the truth value of the match is reversed. For example the lines
<!-- #if referer !~ "my.host.edu" -->would display the "newcomers text" to those clients accessing this document via any link which is not on the host my.host.edu.
Here is some text for newcomers to my site.
<!-- #endif -->
There is also a redirect command which can conditionally cause the server to send an HTTP redirect to a new URL. For example if the text
<!-- #if hostname =~ "\.uk$" -->is included at the beginning of an HTML document then any request from a UK host will automatically be redirected to the specified URL, the UK_mirror_url in this case. This mechanism could also be used to redirect text only browsers to a text only alternative page, etc. There must be no text sent before the <!-- #redirect = "url" --> is entcountered (not even blank lines) since the server cannot send an HTTP redirect while in the middle of tranmitting a document.
<!-- #redirect = "UK_mirror_url" -->
<!-- #endif -->
Normally the URL in the <!-- #redirect = "URL" --> line is fully qualified, like "http://host/path/foo". However, it can also be simply "foo" referring to a file in the same directory as the file being parsed. In this case an HTTP redirection is not sent, and instead the file "foo" is returned immediately to the client.
Often a single regular expression is not adequate to distinguish whether or not to serve some text. For that reason WN allows you to use a file containing any number of regular expressions and serve a document based on whether any of these expressions match accept headers, referer header, user-agent, hostname, etc. For example, if the file "acceptfile" contains the lines
image/gifthen the following conditional text might be appropriate:
image/jpeg
image/x-xbitmap
<!-- #if accept file = "acceptfile" -->
I see you aren't using a text only browser...
<!-- #endif -->
The format of the file "acceptfile" is one grep like regular expression per line. Lines beginning with '#' are taken to be comments. If a regular expression is preceded by the character '!' then that character is skipped but the truth value of the match is reversed. More information about files of regular expressions for conditional text can be found in Appendix C.
<!-- #if accessfile="secret/access" -->will display the included text and the link to "Restricted Local Stuff" only to clients on hosts permitted by the access control file "secret/access."
Here is a link to a restricted directory. <a href="/secret/stuff.html">Restricted Local Stuff</a>
Hosts not listed in the file "secret/access" can't look at it, so why show them a link to it?
<!-- #endif -->
<!-- #section -->
instead of <!-- #include --> and the server will include only the portion of the HTML document between the special comments <!-- #start --> and <!-- #end --> inserted in that document. This requires that these starting and ending comments occur in the HTML document on lines by themselves and with no preceeding white space.
To deal with this case WN uses wrappers. Wrapping a file is the inverse of including it. If you have an index file entry like
File=foo.html
Wrappers=bar.html
then the server will send the file bar.html looking for the marker <!-- #include --> and inserting foo.html at the line where it is found. So this is just like the Includes= directive except the role of which file is included in the other is reversed. If the include marker is never found the entire wrapper, bar.html, is sent first and the main file, foo.html, is appended at the end. Thus the Wrappers= directive can be used to prepend a file without the need of any marker in the main file.
A line like
SearchWrapper=foo.htmlin the directory record of an index file will cause any search of that directory to return an unordered list of matches wrapped with the file foo.html. The list of matches will be inserted into foo.html at a point where the marker <!-- #include --> is found. You can also insert the user supplied search term by using the marker <!-- #query -->. Both of these markers must occur on a line by themselves with no leading white space.
Here is how to do it. Think of all your files, wrappers, includes and the main file arranged as you wish them to be combined for the final served document. Now imagine inserting an opening (or left) parenthesis at the beginning of each file and insert a closing (or right) parenthesis at the end of each file. You should have a legally nested and balanced collection of parentheses. To each of the opening parentheses attach the name of the file which begins at that point. Then write down the list of all the file names in the order their corresponding opening parentheses occur. All the files which come before the main file should be wrappers and should be listed in the Wrappers= line in the order in which they occur in this list. All the files after the main file should be in the Includes= line and should occur in the order they occur in this list.
Here's a simple example. Suppose we have a main file M and other files A,B,C, and D which we want to have nested like
(D...(B...B)...(M...(A...(C...C)...A)...M)...D)
Then the entry in the index file should look like
File=M
Wrappers=D,B
Includes=A,C
<!-- #title -->in the file at the point where the title or search term should be inserted. Both of these markers must occur on a line by themselves with no leading white space.
or
<!-- #query -->
In addition to the title and query user supplied fields can be inserted in documents. This is done by including a marker such as <!-- #field3 --> in the file at the point where the value should be inserted. This should occur on a line by itself with no whitespace before it. You can also insert the value of any environment variable into your text with a line like
<!-- #environ = "HTTP_REFERER" -->which will be replaced by the contents of the environment variable HTTP_REFERER.
Important Note: If there is no Wrappers= or Includes= line in the index file for this entry then there must be a line like
Attributes=parseso the server knows it is to parse the file to look for the marker. See the section concerning attributes in Appendix B for more details. Also if you wish to insert the value of a CGI environment variable (as in the example above) you must have an "Attributes=parse" line.