Welcome to WebmasterWorld Guest from

Forum Moderators: Ocean10000 & incrediBILL & phranque

Message Too Old, No Replies

Language content negotiation on 1.3

Is there an alternative to prefer-language?

10:42 am on Oct 21, 2009 (gmt 0)

5+ Year Member

Since about a year I have been using content negotiation for multi-language sites. And I an very happy with the results. But for a recent site I was confronted with an Apache 1.3 server (Previous sites always ran on 2.x).

The content negotiation works as usual, but since Apace 1.3 doesn't have the "prefer-language" variable it seems to be impossible to override the negotiated language.

I am looking for a (hopefully) simple solution which doesn't involve too much re-writing.

Here's the setup:

All pages have a name like: name.xx.html where xx is the language code.
All these pages reside in the root directory.
The root .htaccess file contains:

Options +MultiViews
AddLanguage en .en
AddLanguage nl .nl
AddLanguage tr .tr
LanguagePriority en nl tr
#ForceLanguagePriority Prefer Fallback
#SetEnvIf Cookie "language=(.+)" prefer-language=$1
#Header append Vary cookie

The last three lines are commented out, since these don't work in 1.3.
On each page I have a choice of language like so:

<li class="language"><a href="modules/change_language.php?lang=en&page=<!--#echo var="DOCUMENT_NAME"-->" lang="en" hreflang="en" title="This page in English">English</a></li>
<li class="language"><a href="modules/change_language.php?lang=nl&page=<!--#echo var="DOCUMENT_NAME"-->" lang="nl" hreflang="nl" title="Deze pagina in het Nederlands">Nederlands</a></li>
<li class="language hidden"><a href="modules/change_language.php?lang=tr&page=<!--#echo var="DOCUMENT_NAME"-->" lang="tr" hreflang="tr" title="Bu sayfa T&uuml;rk&ccedil;ede">T&uuml;rk&ccedil;e</a></li>

With the contents of change_language.php being:

$chosenLanguage = $_GET['lang'];
$currentPage = $_GET['page'];
setcookie('language', $chosenLanguage, time()+60*60*24*365, '/');
$currentPage = preg_replace('/\..*/', '', $currentPage);
header('Location: SERVER_NAME' . $currentPage);

All this works perfectly on apache 2.x, but any help on how to convert this to 1.3. is much appreciated. I was thinking in terms of rewrite? But I am not very good at that.

1:33 pm on Oct 21, 2009 (gmt 0)

WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member

mod_rewrite really doesn't have the 'tools' you need to solve this problem. The main complication is that the Accept-Language header may contain any or all of your supported languages, marked individually or in arbitrary groups with identical or different 'quality scores'. These groups may or may not even be ordered by 'quality' -- Although they should be, there can be no guarantee. It would be quite complex to parse out the 'meaning' of all possible Accept-Language headers using only mod_rewrite, and especially in regard to ranking by 'quality'.

As a result, I'd recommend passing all potentially-unresolvable requests to a script, and let it figure out what language to serve. Or alternatively, upgrading this 'new' server to Apache 2.x.

If you must do this at the server level, look into using RewriteMap to invoke a small script (e.g. PERL) during the URL-to-filepath translation phase. This map must be defined at the server configuration level before it can then be used in .htaccess.

Also, if you have a choice, put as much of your code in the server config files as you can; It will be processed much more efficiently there than in .htaccess.


3:05 pm on Oct 21, 2009 (gmt 0)

5+ Year Member


First off, I don't have access to the config files so I am stuck with the htaccess. For the same reason I cannot upgrade to 2.x

Secondly, I think I wasn't clear enough on the problem I am having. The automatic language selection works as expected, It is the "manual override" that doesn't work.

The server does serve the user the right language, and defaults to "en" if nothing or rubbish is present in the headers. So that works ok.
But... on each page there are links to all the other languages (in case someone wants to manually switch language). And these don't work under 1.3 as they do under 2.x.

In 2.x. you can "read" cookies in htaccess, but this cannot be done in 1.3, I am looking for an alternative to that.

4:27 pm on Oct 21, 2009 (gmt 0)

WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member

You can't set cookies using mod_rewrite in Apache 1.3.x, but you can read them.

Use RewriteCond %{HTTP_COOKIE} <regex-pattern>

Apache2.x added the [CO=] flag to RewriteRule which allows you to set cookies on the server response. In Apache 1.x you can use mod_headers to do it, if you can arrange things such that the Header Set directive can be conditioned based only on placing it in a <Files> or <FilesMatch> container. That is, making the cookie setting function conditional is the main limitation in Apache 1.3.x.


4:51 pm on Oct 21, 2009 (gmt 0)

5+ Year Member

Thanks for the help. Like I said I am terrible at RewriteRules, so just to be clear, would this work?:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_COOKIE} language="en"
RewriteRule ^/(.*)$ /$1.en.html
9:48 pm on Oct 21, 2009 (gmt 0)

WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member

Drop the RewriteBase since it's default.
Avoid unintended substring matches on query.
Prevent recursion.
No leading slash on URL-path pattern in .htaccess or within config file <Directory> containers.
Always use [L] flag unless you can defend the decision not to -- 99.9% of all rules should use [L].

RewriteEngine on
RewriteCond %{HTTP_COOKIE} ^([^&]*&)*language="en"(&.*)?$
RewriteCond $1 !\.en\.html$
RewriteRule ^(.*)$ /$1.en.html [L]

One more recommendation: Drop the quotes on "en" in your cookie string. These may cause untold misery as over the years you will likely end up hunting repeatedly for script code where someone forgot to escape the quotes...


[added] Corrected as noted below [/added]

[edited by: jdMorgan at 2:37 pm (utc) on Oct. 22, 2009]

8:27 am on Oct 22, 2009 (gmt 0)

5+ Year Member


It works, but not as I would like it to work.
Incredible how 3 simple lines for Apache 2 that don't work in 1.3 can have such a big effect.
I am afraid I do need to rewrite the whole language-choice thing in php.

Again, thank you for the help, but it is back to the drawingboard for me :-(

2:39 pm on Oct 22, 2009 (gmt 0)

WebmasterWorld Senior Member jdmorgan is a WebmasterWorld Top Contributor of All Time 10+ Year Member

Well, I got in a hurry, and forgot to negate the pattern in the second RewriteCond (see corrected code above).

If you did not detect and correct this problem before testing, I suggest making the correction and trying again.

Sorry, but sometimes it's hard just to 'keep up' with my day... :o



Featured Threads

Hot Threads This Week

Hot Threads This Month