How to configure Nginx for XHTML with XSLT
Despite its clunky syntax, XSLT can be an excellent tool for prototyping new websites. This article describes how to configure Nginx to serve XSLT-processed XHTML.
- Author:
- [TODO name], [TODO position or role of first author]
- First Published:
- by
Nelkinda Software Craft Private Limited
- Last Modified:
- by [TODO name]
- Approximate reading time:
1 Background: XSLT processing stages
XSLT processing can happen at various stages. The possible stages are:
- Build-time (before upload)
- Server-side (which this article describes using Nginx)
- Client-side
Each of these processing stages has their advantages and disadvantages. There is no single best stage or solution around XSLT. What is best for a given use case depends on its particular situation.
1.1 Build-time XSLT processing
Build-time XSLT processing is the most powerful, and also the greenest way. All XSLT processing is done as part of the build and deployment pipeline. The biggest advantage is the free choice of XSLT processor. When doing build-time XSLT processing, Saxon can be used. The biggest advantage of Saxon is that it implements XSLT 3.0. The disadvantage is that this increases the turn-around time. While the turn-around time isn't much, it still impacts rapid prototyping.
1.2 Server-side XSLT processing
Server-side XSLT processing is almost as non-green as client-side XSLT processing. Compared to client-side XSLT processing, it has two advantages. One is that it can be faster, because the transformations don't need to be loaded via the network. The other is that the client doesn't see XSLT. This can be helpful in case the client also needs to run a JavaScript which is bogus and doesn't work as soon as XSLT is involved. The possibilities are limited by whatever the web server's XSLT module provides. For example, Nginx Module ngx_http_xslt_module uses libxslt which provides XSLT 1.0. If you want a server that performs XSLT 3.0 processing, you probably have to use Saxon and customize your server. Although I haven't done such a customization, I would guess that it's quite simple to setup for Java, for example, Tomcat, JavaScript, for example, Node, or C#.
1.3 Client-side XSLT processing
Client-side XSLT processing is the easiest to setup, because actually no specific setup is required. There are at least four drawbacks around Client-side XSLT processing.
- It's not "green". The same transformation would happen on lots of different clients, wasting CPU time.
- It can be network-heavy. All the transformations (stylesheets) have to be loaded from the network.
- The interaction with JavaScript is browser-specific. For example, Chrome processes JavaScript before and after XSLT. Whereas Firefox processes JavaScript only after XSLT.
- The interaction of JavaScript with the DOM can be altered and break XML-unaware JavaScript code.
2 The nginx.conf
file
The following file is the nginx configuration file.
nginx.conf
configuration file for NginxLet's look at the key elements. XSLT is not available by default. The loadable module is usually built and installed but not activated (loaded). It has to be activated by loading it explicitly from the nginx.conf
configuration file. That's what load_module
does.
index
determines the page to be loaded for directories. This defaults to index.html
, although that actually is just historic convention and doesn't really make sense. Only in the rarest cases does the page named index.html
actually contain an index. It usually is just the entry point, the start. That's why I prefer to call it start.xhtml
instead of index.html
. Oh, and, of course, .xhtml
instead of .html
to serve application/xhtml+xml
instead of text/html
.
xslt_stylesheet
tells Nginx the XSLT that is to be applied. And xslt_types
tells Nginx the mime types on which the XSLT is to be applied, besides text/xml
.
3 The Sample Transformation
To demonstrate XSLT processing, I use an example which is simple, but at the same time has a certain structure that allows for easy extension to develop larger transformations. The transformation therefore consists of three files:
identity.xslt
- The fallback to just copy attributes and nodes from the source tree and continue recursion when no specific template was defined.
html.xslt
- Configures the transformation for (X)HTML. It doesn't do anything besides defining from which HTML elements whitespace may be removed. This way, the XSLT transformation also minifies the XHTML files on the fly.
layout.xslt
- This is the actual transformation. Besides importing the two aforementioned transformations, it adds a CSS, a header, and a footer.
4 Launching Nginx with Docker
To launch Nginx with Docker, we need a couple of things:
- A port number on which Nginx should run, if we want to map Nginx to localhost.
- A name for the container so that we can refer to it reliably.
- A volume for the configuration file.
- A volume for the regular content.
- A volume for the XSLT transformations.