Michael Dayah of Ptable.com asked about how to extend the technique from Serving XHTML with Apache MultiViews and Serving Pre-Compressed Files with Apache MultiViews to serve files for a language requested using a query parameter. This post outlines the slick technique we worked out.
Initially we investigated using
mod_rewrite and
mod_headers in
various ways. Unfortunately, it appears that
mod_negotiation
(which implements MultiViews
) performs negotiation in the type_checker
hook of the preparation phase of request
processing
(see
mod_negotiation.c:3212)
which is before the fixup
hook used by mod_headers (see
mod_headers.c:1007)
and mod_rewrite (see
mod_rewrite.c:5315).
This prevents header or environment changes made by those modules from
affecting MultiViews negotiation, unless other trickery (e.g. sub-requests) is
used.
The solution we came up with is to use
SetEnvIfExpr
from
mod_setenvif to
set the prefer-language
environment
variable.
For example, to use the language from a query parameter named lang
if it
contains a value which might be a valid Basic Language
Range for
Accept-Language:
Options +MultiViews
SetEnvIfExpr "%{QUERY_STRING} =~ /(?:^|&)lang=([A-Za-z]{1,8}(?:-[A-Za-z0-9]{1,8})*)(?:&|$)/" prefer-language=$1
This combination should be sufficient for requests such as GET
/index.html?lang=fr
to return index.html.fr
regardless of the value in the
Accept-Language
request header, if present.
Note: The mapping from language tags to file extensions is configured by
AddLanguage
.
On Debian, the default mapping is defined in
/etc/apache2/mods-available/mime.conf
(linked from
/etc/apache2/mods-enabled/mime.conf
when mod_mime is enabled) and can be
changed using RemoveLanguage
/AddLanguage
as desired.
Best of luck!