The last key piece to AxKit is how everything is tied together. We have a clean separation of logic, presentation, and content, but we've only briefly introduced using processing instructions for setting up the way a file gets processed through the AxKit engine. A generally better and more scalable way to work is to use the AxKit configuration directives to specify how to process files through the system.

Before introducing the configuration directives in detail, it is worth looking at how the W3C sees the evolving web of new media types. The HTML 4.0 specification defines eight media types:

screen
The default media type, for normal web browsers.

tty
For tty-based devices (e.g., the Lynx web browser).

printer
For printers requesting content directly (rather than for printable versions of a HTML page). Also for PDF or other paginated content.

handheld
For handheld devices. You need to distinguish between WAP, cHTML, and other handheld formats using styles, because the W3C did not make this distinction when it defined the media types.

braille
For braille interpreters.

tv
For devices with a TV-based browser, such as Microsoft's WebTV and Sega's Dreamcast.

projection
For projectors or presentations.

aural
For devices that can convert the output to spoken words, such as VoiceXML.

AxKit allows you to plug in modules that can detect these different media types, so you can deliver the same content in different ways. For finer control, you can use named stylesheets. In named stylesheets, you might have a printable page output to the screen media type. Named stylesheets are seen on many magazine sites (e.g., http://take23.org/) for displaying multi-page articles.

For example, to map all files with the extension .dkb to a DocBook stylesheet, you would use the following directives:

<Files *.dkb>
AxAddProcessor text/xsl /stylesheet/docbook.xsl
</Files>

Now if you wanted to display those DocBook files on WebTV as well as ordinary web browsers, but you wanted to use a different stylesheet for WebTV, you would use:

<Files *.dkb>
  <AxMediaType tv>
    AxAddProcessor text/xsl /stylesheets/docbook_tv.xsl
  </AxMediaType>
  <AxMediaType screen>
    AxAddProcessor text/xsl /stylesheets/docbook_screen.xsl
  </AxMediaType>
</Files>

Now let's extend that to chained transformations. Let's say you want to build up a table of contents the same way in both views. One way you can do it is to modularize the stylesheet. However, it's also possible to chain transformations in AxKit, simply by defining more than one processor for a particular resource:

<Files *.dkb>
  AxAddProcessor text/xsl /stylesheets/docbook_toc.xsl
  <AxMediaType tv>
    AxAddProcessor text/xsl /stylesheets/docbook_tv.xsl
  </AxMediaType>
  <AxMediaType screen>
    AxAddProcessor text/xsl /stylesheets/docbook_screen.xsl
  </AxMediaType>
</Files>

Now the TV-based browsers will see the DocBook files transformed by docbook_toc.xsl, with the output of that transformation processed by docbook_tv.xsl.

This is exactly how we would build up an application using XSP:

<Files *.xsp>
  AxAddProcessor application/x-xsp .
  <AxMediaType tv>
    AxAddProcessor text/xsl /stylesheets/page2tv.xsl
  </AxMediaType>
  <AxMediaType screen>
    AxAddProcessor text/xsl /stylesheets/page2html.xsl
  </AxMediaType>
</Files>

This resolves the earlier issue we had where the XSP did not output HTML, but something entirely different. Now we can see why—because this way we can build dynamic web applications that work easily on different devices!

There are four other configuration directives similar to AxAddProcessor. They take two additional parameters: one that specifies a particular way to examine the file being processed and one to facilitate the match. The directives are:

AxAddRootProcessor
Takes a root element name to match the first (root) element in the XML document. For example:

AxAddRootProcessor text/xsl article.xsl article

processes all XML files with a root element of <article> with the article.xsl stylesheet.

AxAddDocTypeProcessor
Processes XML documents with the given XML public identifier.

AxAddDTDProcessor
Processes all XML documents that use the DTD given as the third option.

AxAddURIProcessor
Processes all resources at the matching URI (which is a Perl regex).

This option was added for two reasons: because the <LocationMatch> directive is not allowed in an .htaccess file, and because the built-in Apache regular expressions are not powerful enough—for example, they cannot do negative matches.

Finally, the <AxStyleName> block allows you to specify named stylesheets. An example that implements printable/default views of a document might be:

<AxMediaType screen>
  <AxStyleName #default>
    AxAddProcessor text/xsl /styles/article_html.xsl
  </AxStyleName>
  <AxStyleName printable>
    AxAddProcessor text/xsl /styles/article_html_print.xsl
  </AxStyleName>
</AxMediaType>

By mixing the various embedded tags, it is possible to build up a very feature-rich site map of how your files get processed.