I am working on an application that will be launched in a number of languages. I wanted to do something fun for the language settings, so I decided that the languages would be auto-detecting, user-changeable, and served via automatic sub-domains.
So, english will be en.domain.com and french will be fr.domain.com. What follows is my attempt at making that happen within cakePHP. There may be better, more concise, or more “cake friendly” manners of doing this, so please speak up in the comments and let me know.
I set up my app_controller.php to have a beforeFilter() that tests for the subdomain, if it doesn’t find a language subdomain, it tries to figure out what the language subdomain should be, then it redirects to that. First, if the user has selected a language and it’s in their cookie, they get that language. Then the application checks to see what language their browser is set to (I’m using a LanguageDetection component here that I cobbled together from a few sources). Then finally, if that doesn’t work, it defaults to english.
function beforeFilter() { //get the parts of the host string ( lang dot domain dot com/org/edu ) $host_r = explode('.', $this->Session->host); //make sure that "www" does not get checked in language subdomain checker if($host_r[0]=='www') array_shift($host_r);if(count($host_r)==3) { $langtester = $host_r[0]; if(in_array($langtester, $this->langarr)) { define('LANG',$langtester); } else { define('LANG','en'); } } else if(count($host_r)==2) { $thebrowserlang = $this->LanguageDetection->getLangArr(); if(in_array($this->Cookie->read('User.lang'), $this->langarr)) { $this->redirect('http://'.$this->Cookie->read('User.lang').'.'.$this->Session->host); exit(); } else if(array_key_exists($thebrowserlang[1], $this->langarr)) { $this->redirect('http://'.$thebrowserlang[1].'.'.$this->Session->host.'/domain/'); exit(); } else { $this->redirect('http://en.'.$this->Session->host.'/domain/'); exit(); } } $this->set('all_languages', $this->langarr); }
Now, the host should be en.domain.com for the user english user.
Here is a link to that language detection component you’ll need to pull this off. Put it in your controllers/components/ directory (turning it into a php file, of course) and include it with the components array in app_controller.
Now, once a user hits the site, they always end up with a language setting, even if it’s the default english. This means that “LANG” is defined across the application as the language they are using to view the site. When you want to display information for them, you can put this beforeFind in a model that contains language specific items:
function beforeFind($queryData)
{
$queryData['conditions']['lang'] = LANG;
return $queryData;
}
This way, the find query always has the user’s current language as a condition for any data it’s pulling out.
I’m using a couple models that span languages (meta groups to relate multiple language entries to each other) so those have no language column in the table and so don’t need this sort of information in the query. So I leave this out of those models.
Sphere: Related Content