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.

Data Model Questions

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


Reply

8 Posts   2727 Views

Avatar
bkausbk

12 February 2010 at 4:20am (Last edited: 17 February 2010 11:16pm), Community Member, 11 Posts

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

12 February 2010 at 5:55am Community Member, 80 Posts

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

12 February 2010 at 6:08am (Last edited: 22 February 2010 10:01pm), Community Member, 11 Posts

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

Avatar
bkausbk

17 February 2010 at 9:43pm (Last edited: 18 February 2010 2:52am), Community Member, 11 Posts

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

30 April 2010 at 8:13pm Community Member, 19 Posts

Thanks! That hint was really helpful.

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

Avatar
bkausbk

30 April 2010 at 9:34pm Community Member, 11 Posts

Correct location is in Translatable::set_current_locale()

Avatar
perelin

4 March 2013 at 6:44am (Last edited: 4 March 2013 6:45am), Community Member, 4 Posts

@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

4 March 2013 at 6:49am (Last edited: 4 March 2013 6:50am), Community Member, 4 Posts

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');
      }
   }
}