/** * Get a set of content languages (for quick language navigation) * @example * <code> * <!-- in your template --> * <ul class="langNav"> * <% loop Languages %> * <li><a href="$Link" class="$LinkingMode" title="$Title.ATT">$Language</a></li> * <% end_loop %> * </ul> * </code> * * @return ArrayList|null */ public function Languages() { $locales = TranslatableUtility::get_content_languages(); // there's no need to show a navigation when there's less than 2 languages. So return null if (count($locales) < 2) { return null; } $currentLocale = Translatable::get_current_locale(); $homeTranslated = null; if ($home = SiteTree::get_by_link('home')) { /** @var SiteTree $homeTranslated */ $homeTranslated = $home->getTranslation($currentLocale); } /** @var ArrayList $langSet */ $langSet = ArrayList::create(); foreach ($locales as $locale => $name) { Translatable::set_current_locale($locale); /** @var SiteTree $translation */ $translation = $this->owner->hasTranslation($locale) ? $this->owner->getTranslation($locale) : null; $langSet->push(new ArrayData(array('Locale' => $locale, 'RFC1766' => i18n::convert_rfc1766($locale), 'Language' => DBField::create_field('Varchar', strtoupper(i18n::get_lang_from_locale($locale))), 'Title' => DBField::create_field('Varchar', html_entity_decode(i18n::get_language_name(i18n::get_lang_from_locale($locale), true), ENT_NOQUOTES, 'UTF-8')), 'LinkingMode' => $currentLocale == $locale ? 'current' : 'link', 'Link' => $translation ? $translation->AbsoluteLink() : ($homeTranslated ? $homeTranslated->Link() : '')))); } Translatable::set_current_locale($currentLocale); i18n::set_locale($currentLocale); return $langSet; }
/** * Retrieves information about this object in the CURRENT locale * * @param string $locale The locale information to request, or null to use the default locale * @return ArrayData Mapped list of locale properties */ public function CurrentLocaleInformation() { $locale = Fluent::current_locale(); // Store basic locale information $data = array('Locale' => $locale, 'LocaleRFC1766' => i18n::convert_rfc1766($locale), 'Alias' => Fluent::alias($locale), 'Title' => i18n::get_locale_name($locale), 'LanguageNative' => i18n::get_language_name(i18n::get_lang_from_locale($locale), true)); return new ArrayData($data); }
/** * Retrieves information about this object in the specified locale * * @param string $locale The locale information to request, or null to use the default locale * @return ArrayData Mapped list of locale properties */ public function LocaleInformation($locale = null) { // Check locale if (empty($locale)) { $locale = Fluent::default_locale(); } // Check linking mode $linkingMode = 'link'; if ($this->owner->hasMethod('canViewInLocale') && !$this->owner->canViewInLocale($locale)) { $linkingMode = 'invalid'; } elseif ($locale === Fluent::current_locale()) { $linkingMode = 'current'; } // Check link $link = $this->owner->LocaleLink($locale); // Store basic locale information $data = array('Locale' => $locale, 'LocaleRFC1766' => i18n::convert_rfc1766($locale), 'Alias' => Fluent::alias($locale), 'Title' => i18n::get_locale_name($locale), 'LanguageNative' => i18n::get_language_name(i18n::get_lang_from_locale($locale), true), 'Link' => $link, 'AbsoluteLink' => $link ? Director::absoluteURL($link) : null, 'LinkingMode' => $linkingMode); return new ArrayData($data); }
/** * * Fetch a native language string from the `i18n` class via a passed locale * in the format "XX_xx". In the event a match cannot be found in any framework * resource, an empty string is returned. * * @param string $locale e.g. "pt_BR" * @return string The native language string for that locale e.g. "português (Brazil)" */ public static function locale_native_name($locale) { // Attempts to fetch the native language string via the `i18n::$common_languages` array if ($native = i18n::get_language_name(i18n::get_lang_from_locale($locale), true)) { return $native; } // Attempts to fetch the native language string via the `i18n::$common_locales` array $commonLocales = i18n::get_common_locales(true); if (!empty($commonLocales[$locale])) { return $commonLocales[$locale]; } // Nothing else to go on, so return an empty string for a consistent API return ''; }
/** * Get a tabset with a tab for every language containing the translatable fields. * Example usage: * <code> * public function getCMSFields(){ * $fields = FieldList::create(); * $fields->add($this->getTranslatableTabSet()); * return $fields; * } * </code> * @param string $title the title of the tabset to return. Defaults to "Root" * @param bool $showNativeFields whether or not to show native tab labels (eg. Español instead of Spanish) * @return TabSet */ public function getTranslatableTabSet($title = 'Root', $showNativeFields = true) { /** @var TabSet $set */ $set = TabSet::create($title); // get target locales $locales = self::get_target_locales(); // get translated fields $fieldNames = self::get_localized_class_fields($this->owner->class); if (empty($fieldNames)) { user_error('No localized fields for the given object found', E_USER_WARNING); } $ambiguity = array(); foreach ($locales as $locale) { $langCode = i18n::get_lang_from_locale($locale); foreach ($locales as $l) { if ($l != $locale && i18n::get_lang_from_locale($l) == $langCode) { $parts = explode('_', $l); $localePart = end($parts); $ambiguity[$l] = $localePart; } } } foreach ($locales as $locale) { if (!$this->canTranslate(null, $locale)) { continue; } $lang = i18n::get_language_name(i18n::get_lang_from_locale($locale), $showNativeFields); if (!$lang) { // fallback if get_lang_name doesn't return anything for the language code $lang = i18n::get_language_name($locale, $showNativeFields); } $langName = ucfirst(html_entity_decode($lang, ENT_NOQUOTES, 'UTF-8')); if (isset($ambiguity[$locale])) { $langName .= ' (' . $ambiguity[$locale] . ')'; } /** @var Tab $tab */ $tab = Tab::create($locale, $langName); foreach ($fieldNames as $fieldName) { $tab->push($this->getLocalizedFormField($fieldName, $locale)); } $set->push($tab); } return $set; }
public function testGetLanguageName() { Config::inst()->update('i18n', 'common_languages', array('de_CGN' => array('name' => 'German (Cologne)', 'native' => 'Kölsch'))); $this->assertEquals('German (Cologne)', i18n::get_language_name('de_CGN')); $this->assertEquals('Kölsch', i18n::get_language_name('de_CGN', true)); }
/** * Change the member dialog in the CMS * * This method updates the forms in the cms to allow the translations for * the defined translatable fields. */ function updateCMSFields(FieldSet &$fields) { if (!$this->stat('enabled')) { return false; } $creating = false; $baseClass = $this->owner->class; while (($p = get_parent_class($baseClass)) != "DataObject") { $baseClass = $p; } $allFields = $this->owner->getAllFields(); if (!self::is_default_lang()) { // Get the original version record, to show the original values if (!is_numeric($allFields['ID'])) { $originalLangID = Session::get($this->owner->ID . '_originalLangID'); $creating = true; } else { $originalLangID = $allFields['ID']; } $originalRecord = self::get_one_by_lang($this->owner->class, self::$default_lang, "`{$baseClass}`.ID = " . $originalLangID); $this->original_values = $originalRecord->getAllFields(); $alltasks = array('dup' => array()); foreach ($fields as $field) { if ($field->isComposite()) { $innertasks = $this->duplicateOrReplaceFields($field->FieldSet()); // more efficient and safe than array_merge_recursive $alltasks['dup'] = array_merge($alltasks['dup'], $innertasks['dup']); } } foreach ($alltasks['dup'] as $fieldname => $newfield) { // Duplicate the field $fields->replaceField($fieldname, $newfield); } } else { $alreadyTranslatedLangs = null; if (is_numeric($allFields['ID'])) { $alreadyTranslatedLangs = self::get_langs_by_id($baseClass, $allFields['ID']); } if (!$alreadyTranslatedLangs) { $alreadyTranslatedLangs = array(); } foreach ($alreadyTranslatedLangs as $i => $langCode) { $alreadyTranslatedLangs[$i] = i18n::get_language_name($langCode); } $fields->addFieldsToTab('Root', new Tab(_t('Translatable.TRANSLATIONS', 'Translations'), new HeaderField(_t('Translatable.CREATE', 'Create new translation'), 2), $langDropdown = new LanguageDropdownField("NewTransLang", _t('Translatable.NEWLANGUAGE', 'New language'), $alreadyTranslatedLangs), $createButton = new InlineFormAction('createtranslation', _t('Translatable.CREATEBUTTON', 'Create')))); if (count($alreadyTranslatedLangs)) { $fields->addFieldsToTab('Root.Translations', new FieldSet(new HeaderField(_t('Translatable.EXISTING', 'Existing translations:'), 3), new LiteralField('existingtrans', implode(', ', $alreadyTranslatedLangs)))); } $langDropdown->addExtraClass('languageDropdown'); $createButton->addExtraClass('createTranslationButton'); $createButton->includeDefaultJS(false); } }
/** * Get the name of the language that we are translating in */ function EditingLang() { if (!Translatable::is_default_lang()) { return i18n::get_language_name(Translatable::current_lang()); } else { return false; } }
function updateCMSFields(FieldSet &$fields) { if(!$this->stat('enabled', true)) return false; // add hidden fields for the used language and original record $fields->push(new HiddenField("Lang", "Lang", $this->getLang()) ); $fields->push(new HiddenField("OriginalID", "OriginalID", $this->owner->OriginalID) ); // if a language other than default language is used, we're in "translation mode", // hence have to modify the original fields $isTranslationMode = (Translatable::default_lang() != $this->getLang() && $this->getLang()); if($isTranslationMode) { $originalLangID = Session::get($this->owner->ID . '_originalLangID'); $translatableFieldNames = $this->getTranslatableFields(); $allDataFields = $fields->dataFields(); $transformation = new Translatable_Transformation(Translatable::get_original($this->owner->class, $this->owner->ID)); // iterate through sequential list of all datafields in fieldset // (fields are object references, so we can replace them with the translatable CompositeField) foreach($allDataFields as $dataField) { if(in_array($dataField->Name(), $translatableFieldNames)) { //var_dump($dataField->Name()); // if the field is translatable, perform transformation $fields->replaceField($dataField->Name(), $transformation->transformFormField($dataField)); } else { // else field shouldn't be editable in translation-mode, make readonly $fields->replaceField($dataField->Name(), $dataField->performReadonlyTransformation()); } } } else { // if we're not in "translation mode", show a dropdown to create a new translation. // this action should just be possible when showing the default language, // you can't create new translations from within a "translation mode" form. $alreadyTranslatedLangs = array(); foreach ($alreadyTranslatedLangs as $i => $langCode) { $alreadyTranslatedLangs[$i] = i18n::get_language_name($langCode); } $fields->addFieldsToTab( 'Root', new Tab(_t('Translatable.TRANSLATIONS', 'Translations'), new HeaderField('CreateTransHeader', _t('Translatable.CREATE', 'Create new translation'), 2), $langDropdown = new LanguageDropdownField("NewTransLang", _t('Translatable.NEWLANGUAGE', 'New language'), $alreadyTranslatedLangs), $createButton = new InlineFormAction('createtranslation',_t('Translatable.CREATEBUTTON', 'Create')) ) ); if (count($alreadyTranslatedLangs)) { $fields->addFieldsToTab( 'Root.Translations', new FieldSet( new HeaderField('ExistingTransHeader', _t('Translatable.EXISTING', 'Existing translations:'), 3), new LiteralField('existingtrans',implode(', ',$alreadyTranslatedLangs)) ) ); } $langDropdown->addExtraClass('languageDropdown'); $createButton->addExtraClass('createTranslationButton'); $createButton->includeDefaultJS(false); } }
public static function MemberLocales() { if (self::$locales) { return self::$locales; } self::$locales = array(); $object = singleton(Config::inst()->get('PostmarkAdmin', 'member_class')); if ($db = $object->db()) { if (array_key_exists('Locale', $db)) { $locales = DB::query('SELECT DISTINCT Locale AS Locale FROM ' . Config::inst()->get('PostmarkAdmin', 'member_class') . ' WHERE Locale IS NOT NULL'); foreach ($locales as $row) { self::$locales[$row['Locale']] = i18n::get_language_name(substr($row['Locale'], 0, 2)); } } } return self::$locales; }
/** * Returns the language name * * @param string $locale Locale to get name for * @param string $in_locale Locale to display name in (when PHP intl is not installed, this is the indicator for native displaying) * * @return string */ public static function getDisplayLanguage($locale, $in_locale) { if (class_exists('Locale')) { $languageName = Locale::getDisplayLanguage($locale, $in_locale); } else { $native = false; if ($locale == $in_locale) { $native = true; } $languageName = i18n::get_language_name(substr($locale, 0, strpos($locale, '_')), $native); if (empty($languageName)) { $common_locales = i18n::get_common_locales($native); $all_locales = (array) Config::inst()->get('i18n', 'all_locales'); if (array_key_exists($locale, $common_locales)) { $languageName = $common_locales[$locale]; } elseif (array_key_exists($locale, $all_locales)) { $languageName = $all_locales[$locale]; } } } return $languageName; }