homepage Welcome to WebmasterWorld Guest from 54.197.215.146
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Pubcon Platinum Sponsor 2014
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
Language content negotiation on 1.3
Is there an alternative to prefer-language?
Bert36




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

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:


<?php
$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.

 

jdMorgan




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

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.

Jim

Bert36




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

Hi,

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.

jdMorgan




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

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.

Jim

Bert36




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

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

jdMorgan




msg:4011092
 9:48 pm on Oct 21, 2009 (gmt 0)

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...

Jim

[added] Corrected as noted below [/added]

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

Bert36




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

Hi,

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 :-(

jdMorgan




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

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

Jim

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved