Language negotiation is one of the problems one has to solve when building a multilingual website. I've tried various methods and, although I don't usually prefer it on simple sites, the best one seems to be "domain name" negotiation.
This way every language has its own domain, whatever you choose it to be. Since I build sites in Greek and English I go with http://example.gr and http://en.example.gr for each language accordingly.
There is one problem by using this method and one drawback. The drawback is that since you use different domains you need to re-login in the site if you change language, not good but I can live with it.
The problem is that when you move data between the dev stage live environments you end having your site pointing to the wrong domain (eg stage points to en.dev.example.com).
There is a discussion about it going on here and a module that promises to solve this, but only for Drupal 7, right here.
After reading the discussion on d.o. I decided that I should somehow automate the solution people provided.
So I wrote a bash script that, after moving your database between environments, makes the changes needed for your site to work.
It uses Drush and drush-aliases. Subdomains and alias names must be the same for the script to work, although you could easily change it to your liking.
#!/bin/bash
function fix-lang (){
if [ $1 ]
then
if [ $1 = "live" ]
then
drush @$1 sqlq "UPDATE languages SET domain = 'http://en.example.com' WHERE language = 'en'"
drush @$1 sqlq "UPDATE languages SET domain = 'http://el.example.com' WHERE language = 'el'"
drush @$1 cc 'all'
echo "ALL DONE"
elif [ $1 != "live" ]
then
drush @$1 sqlq "UPDATE languages SET domain = 'http://en.$1.example.com' WHERE language = 'en'"
drush @$1 sqlq "UPDATE languages SET domain = 'http://el.$1.example.com' WHERE language = 'el'"
drush @$1 cc 'all'
echo "ALL DONE"
fi
else
echo "No site specified"
fi
}
#!/bin/bash
function fix-lang (){
if [ $1 ]
then
if [ $1 = "live" ]
then
drush @$1 sqlq "UPDATE languages SET domain = 'http://en.example.com' WHERE language = 'en'"
drush @$1 sqlq "UPDATE languages SET domain = 'http://el.example.com' WHERE language = 'el'"
drush @$1 cc 'all'
echo "ALL DONE"
elif [ $1 != "live" ]
then
drush @$1 sqlq "UPDATE languages SET domain = 'http://en.$1.example.com' WHERE language = 'en'"
drush @$1 sqlq "UPDATE languages SET domain = 'http://el.$1.example.com' WHERE language = 'el'"
drush @$1 cc 'all'
echo "ALL DONE"
fi
else
echo "No site specified"
fi
}
As you can see the domain is hardcoded inside the script. Since I use a different unix account for each of my clients this is no problem, I change the script accordingly for every site.
Hope it helps you with multilingual sites and if you've come up with a different solution I'd love to see it!
You simple paste the above code in your .bashrc or .bash_profile, adapt it to your needs and run it like this.fix-lang dev
or whatever you name your environment! If you run fix-lang live
the script will understand that you don't deal with a subdomain but with the main domain.