Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Data Model Questions /

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

[SOLVED] Translatable::set_current_locale in _config.php without any effect


Go to End


8 Posts   6238 Views

Avatar
bkausbk

Community Member, 11 Posts

12 February 2010 at 4:20am

Edited: 17/02/2010 11:16pm

Hello,

as I found out, Translatable::set_current_locale("de_DE") hast absolutely no effect.

In mysite/_config.php I set:

Object::add_extension('Page', 'Translatable');
Translatable::enable();
Translatable::set_default_locale("de_DE");
Translatable::set_current_locale("de_DE");

I even tried to set default_locale to "de_DE" in Translateable.php even without effect. Each time I read locale with Translatable::get_current_locale() in my Page_Controller::Init() "en_US" is returned. However my database has correct values set, i.e. all default sites are set to default locale "de_DE".

There is no sense to set Translatable::set_default_locale("de_DE") if it is always ignored.

What I want to do is to select locales by following conditions:

1. Locale should be set to "de_DE" by default
2. Locale should be set to current logged on member locale (if available)
3. Locale should be determined by browser settings ($_SERVER['HTTP_ACCEPT_LANGUAGE'])

As I read, Page_Controller::Init() is the best place to do this, is this right?

By the way using ?locale=de_DE even had no effect, don't know why.

I'm using SS 2.3.4.

Yours,
bkausbk

Avatar
lerni

Community Member, 81 Posts

12 February 2010 at 5:55am

heho

if i remember correct this i because there was non default locale during installation / first dev/build.

as a test I would just clean out the data-base and do a dev/build with the locale set in _config.php

i've set this ons - the last on is for default lang i18n - not for translatable.
Object::add_extension('SiteTree', 'Translatable');
Translatable::set_default_locale('de_DE');
i18n::set_locale('de_DE');

Avatar
bkausbk

Community Member, 11 Posts

12 February 2010 at 6:08am

Edited: 22/02/2010 10:01pm

Thank you lerni, but this couldn't be the problem since each locale column in database has correct values.

Avatar
bkausbk

Community Member, 11 Posts

17 February 2010 at 9:43pm

Edited: 18/02/2010 2:52am

Yes lerni you was right. The problem was caused because some pages were created before Translatable was enabled. I used the tutorial template "Page" for my work. However all pages created before Translatable was activated has Locale set to NULL. This automatically caused the system to use "en_US" Locale.

Some important hint: If you wonder why your main page (http://mysite.com/) is always displayed in wrong language i.e. "English" if default language isn't set to "English" this is caused by following behaviour:

If URL doesn't contains an UrlSegment like for / SilverStripe tries to get the page with UrlSegment "home" and then tries to find a corresponding translated page with the current locale. But if your default language main page UrlSegment isn't "home" but "startseite" or "accueil" you will never get that page, and always the English version is displayed.

Code snippet for detecting browser locale

// First try to detect browser preferred language
if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
	$locales = array();
	
	$list = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
	foreach($list as $part) {
		$priority = '';
		@list($_locale, $priority) = explode(';', $part);
		if ($priority) {
			$priority = substr($priority, 2);
		} else {
			$priority = 1.0;
		}					
		
		if (preg_match('/^([a-zA-Z]+)$/', $_locale, $match)) {
			if (isset(i18n::$likely_subtags[$match[1]])) {
				$_locale = i18n::$likely_subtags[$match[1]];
			} else {
				$_locale = self::default_locale();
			}
		} else if (preg_match('/^([a-zA-Z]+)-([a-zA-Z]+)$/', $_locale, $match)) {
			$_locale = $match[1] . '_' . strtoupper($match[2]);
		} else {
			$_locale = self::default_locale();
		}
		
		if (in_array($_locale, $locales) == false) {
			$locales[$priority] = $_locale;
		}
	}

	// Sort browser locales by priority
	
	krsort($locales);
	
	// Try to find best matching browser locale
	
	foreach($locales as $_locale) {
		if ($langsAvailable) {
			if (isset($langsAvailable[$_locale])) {
				$locale = $_locale;
				break;
			}
		} else if (self::$allowed_locales) {
			if (in_array($_locale, &self::$allowed_locales)) {
				$locale = $_locale;
				break;
			}
		} else {
			if (isset(i18n::$all_locales[$_locale])) {
				$locale = $_locale;
				break;
			}
		}
	} 
}
self::set_current_locale($locale);

Avatar
Martin Pales

Community Member, 19 Posts

30 April 2010 at 8:13pm

Thanks! That hint was really helpful.

Btw. where should I put this code snippet? Into HomePage.php controler's init() ?

Avatar
bkausbk

Community Member, 11 Posts

30 April 2010 at 9:34pm

Correct location is in Translatable::set_current_locale()

Avatar
perelin

Community Member, 4 Posts

4 March 2013 at 6:44am

Edited: 04/03/2013 6:45am

@bkausbk: After searching for HOURS why my site wouldn´t accept the locales i gave it I found your post.

If URL doesn't contains an UrlSegment like for / SilverStripe tries to get the page with UrlSegment "home" and then tries to find a corresponding translated page with the current locale. But if your default language main page UrlSegment isn't "home" but "startseite" or "accueil" you will never get that page, and always the English version is displayed.

Saved my life. thx!

and @Silverstripe: SRSLY?? hardcoding the homepage name as 'home' and failing when it´s not called home? guys...

Avatar
perelin

Community Member, 4 Posts

4 March 2013 at 6:49am

Edited: 04/03/2013 6:50am

If your homepage is not called home but instead is a redirect to some other page you can write a homepage redirect controller that takes care of the redirect to the correct translation like this:

HomePageRedirect.php

class HomePageRedirect extends SiteTree {
}
class HomePageRedirect_Controller extends ContentController {

	public function init() {
		parent::init();

		$server_name_parts = explode('.', $_SERVER["SERVER_NAME"]);
		$tld = end($server_name_parts);
		if($tld == 'DE') {
			Director::redirect('GERMANPAGE');
		} else {
			Director::redirect('ENGLISHPAGE');
		}
	}
}