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.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

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

Current Locale in Language Select


Reply


4 Posts   2215 Views

Avatar
CodeGuerrilla

Community Member, 105 Posts

9 July 2011 at 8:56pm

Hi have a site using Translatable and am detecting the language using browser settings ($_SERVER['HTTP_ACCEPT_LANGUAGE']) this is working great so far my problem is my language select still shows English and won't select the current locale:

<div id="Language">
   <dl id="Translations" class="langselect">
      <dt>
         <a href="#" hreflang="$Locale.RFC1766" title="$Title">
            <span><img class="flag" src="site/images/locale/{$Locale.RFC1766}.png" />$Locale.Nice</span>
         </a>
      </dt>
      <dd>
         <ul>
         <% control Translations %>
            <% if Locale.Nice %>
            <li class="$Locale.RFC1766">
               <a href="$Link" hreflang="$Locale.RFC1766" title="$Title">
               <span><img class="flag" src="site/images/locale/{$Locale.RFC1766}.png" />$Locale.Nice</span>
               </a>
            </li>
            <% end_if %>
         <% end_control %>
      </ul>
      </dd>
   </dl>
</div>

This has been working fine until I forcibly have set the locale using the users browser settings it seems to always default to English (the default locale)

Can anyone provide some advice please?

Avatar
CodeGuerrilla

Community Member, 105 Posts

9 July 2011 at 9:09pm

Edited: 09/07/2011 9:23pm

Just realised that only things using i18n are working as well so menus etc.. are still in English as well this is really strange, would it be better for me just to redirect the current page to the current locale eg: <URL Fragment>/?locale=es_ES ?

Page.php init()

//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
       $langsAvailable = i18n::$common_locales; // from set from allowed locales in _config.php
      
       foreach($locales as $_locale) {
          if (isset($langsAvailable)) {
             if (isset($langsAvailable[$_locale])) {
               $locale = $_locale;
               break;
             }
          } else {
             if (isset(i18n::$all_locales[$_locale])) {
               $locale = $_locale;
               break;
             }
          }
       }
      }
      
      if(!empty($locale)) {
         i18n::set_locale($locale);
      } else {
         // set locale
         if($this->dataRecord->hasExtension('Translatable')) {
            i18n::set_locale($this->dataRecord->Locale);
         }
      }

Avatar
CodeGuerrilla

Community Member, 105 Posts

10 July 2011 at 12:02pm

Edited: 10/07/2011 12:36pm

One step closer I added:

Translatable::set_current_locale($locale);

if(!empty($locale)) {
         i18n::set_locale($locale);
         Translatable::set_current_locale($locale);
      } else {
         // set locale
         if($this->dataRecord->hasExtension('Translatable')) {
            i18n::set_locale($this->dataRecord->Locale);
         }
      }

Now the menu's etc.. work still some fields are still showing in English and the langauge dropdown does not select current Locale, it seems the only way to display correctly is with the &locale=<Locale> on the URL

Avatar
Chris_Bryer

Community Member, 35 Posts

15 July 2011 at 3:43pm

Edited: 15/07/2011 3:43pm

hey CodeGuerilla,
nice approach to presenting preferred language, i havent thought about that approach.. clever :)
although you are setting a current locale, you are still presenting one specific record based on the url.. you may want to try getting the translation of the page.. try something like this (not tested):

$currentLocale = [your locale calculation based on user preference];
$translation = $this->getTranslation($currentLocale);
Director::redirect($translation->Link());

set_current_locale isnt strong enough to return translated records, it may affect javascript i18n if you are setting <html lang="$Locale">, but it doesnt translate the current record..

hope it gets you somewhere
-Chris