function updateLinkForm(&$form) { $field = new LanguageDropdownField('Language', _t('CMSMain.LANGUAGEDROPDOWNLABEL', 'Language')); $field->setValue(Translatable::get_current_locale()); $field->setForm($form); $form->Fields()->insertBefore($field, 'internal'); Requirements::javascript('translatable/javascript/HtmlEditorField.Translatable.js'); }
/** * Returns a LanguageDropdownField instance used as a default for form * scaffolding. * * @param string $title Optional. Localized title of the generated instance * @param array $params Optional. * * @return FormField * * @author Sebastian Diel <*****@*****.**> * @since 20.03.2013 */ public function scaffoldFormField($title = null, $params = null) { if (is_null($title)) { $title = _t('SilvercartConfig.TRANSLATION'); } $instance = null; $alreadyTranslatedLocales = array(); $translatingClass = 'SiteTree'; if (array_key_exists('object', $params)) { $translatingClass = $params['object']->ClassName; $instance = $params['object']; } if ($instance) { $alreadyTranslatedLocales = $instance->getTranslatedLocales(); unset($alreadyTranslatedLocales[$instance->Locale]); } $localeDropdown = new LanguageDropdownField($this->name, $title, $alreadyTranslatedLocales, $translatingClass, 'Locale-Native', $instance); $currentLocale = Translatable::get_current_locale(); $localesWithTitle = $localeDropdown->getSource(); $usedLocalesWithTitle = Translatable::get_existing_content_languages('SiteTree'); $languageList = array(); $usedLanguageList = array(); foreach ($localesWithTitle as $locale => $localeTitle) { if (is_array($localeTitle)) { foreach ($localeTitle as $locale2 => $title2) { $title2 = SilvercartLanguageHelper::getLanguageDisplayTitle($locale2, $currentLocale); if (array_key_exists($locale2, $usedLocalesWithTitle)) { $usedLanguageList[$locale2] = $title2; unset($languageList[$locale2]); } else { $languageList[$locale2] = $title2; } } } else { $localeTitle = SilvercartLanguageHelper::getLanguageDisplayTitle($locale, $currentLocale); if (array_key_exists($locale, $usedLocalesWithTitle)) { $usedLanguageList[$locale] = $localeTitle; unset($languageList[$locale]); } else { $languageList[$locale] = $localeTitle; } } } asort($languageList); if (count($usedLanguageList)) { asort($usedLanguageList); $languageList = array(_t('Form.LANGAVAIL', "Available languages") => $usedLanguageList, _t('Form.LANGAOTHER', "Other languages") => $languageList); } $localeDropdown->setSource($languageList); return $localeDropdown; }
/** * Returns a form with all languages with languages already used appearing first. * * @return Form */ public function updateSearchForm(Form $form) { $member = Member::currentUser(); //check to see if the current user can switch langs or not if (Permission::checkMember($member, 'VIEW_LANGS')) { $field = new LanguageDropdownField('Locale', _t('CMSMain.LANGUAGEDROPDOWNLABEL', 'Language'), array(), 'SiteTree', 'Locale-English', singleton('SiteTree')); $field->setValue(Translatable::get_current_locale())->setForm($form); } else { // user doesn't have permission to switch langs // so just show a string displaying current language $field = new LiteralField('Locale', i18n::get_locale_name(Translatable::get_current_locale())); } $form->Fields()->unshift($field); }
/** * @param $locale * @return mixed */ public function getLanguageDropdownField($locale) { $locale = Translatable::get_current_locale(); $translation = _t('CMSMain.LANGUAGEDROPDOWNLABEL', 'Language'); $field = LanguageDropdownField::create('Locale', $translation, array(), 'SiteTree', 'Locale-English', singleton('SiteTree')); $field->setValue($locale); return $field; }
/** * Returns a form with all languages with languages already used appearing first. * * @return Form */ function LangForm() { $member = Member::currentUser(); //check to see if the current user can switch langs or not if (Permission::checkMember($member, 'VIEW_LANGS')) { $field = new LanguageDropdownField('Locale', _t('CMSMain.LANGUAGEDROPDOWNLABEL', 'Language'), array(), 'SiteTree', 'Locale-English', singleton('SiteTree')); $field->setValue(Translatable::get_current_locale()); } else { // user doesn't have permission to switch langs // so just show a string displaying current language $field = new LiteralField('Locale', i18n::get_locale_name(Translatable::get_current_locale())); } $form = new Form($this->owner, 'LangForm', new FieldList($field), new FieldList(new FormAction('selectlang', _t('CMSMain_left.GO', 'Go')))); $form->unsetValidator(); $form->addExtraClass('nostyle'); return $form; }
/** * Presents a form to select a language to translate the pages selected with batch actions into. * * @param string $pageIDs | null * @return Form $form */ public function TranslatePagesForm($pageIDs = null) { Versioned::reading_stage('Stage'); // Needs this for changes to effect draft tree $languages = Translatable::get_allowed_locales(); $action = FormAction::create('doTranslatePages', 'Translate')->setUseButtonTag('true')->addExtraClass('ss-ui-button ss-ui-action-constructive batch-form-actions')->setUseButtonTag(true); $actions = FieldList::create($action); $allFields = new CompositeField(); $allFields->addExtraClass('batch-form-body'); if ($pageIDs == null) { $pageIDs = $this->getRequest()->getVar('PageIDs'); } else { $allFields->push(new LiteralField("ErrorParent", '<p class="message bad">Invalid parent selected, please choose another</p>')); } $allFields->push(new HiddenField("PageIDs", "PageIDs", $pageIDs)); $allFields->push(LanguageDropdownField::create("NewTransLang", _t('Translatable.NEWLANGUAGE', 'New language'), $languages)); $headings = new CompositeField(new LiteralField('Heading', sprintf('<h3 class="">%s</h3>', _t('HtmlEditorField.MOVE', 'Choose Language...')))); $headings->addExtraClass('cms-content-header batch-pages'); $fields = new FieldList($headings, $allFields); $form = Form::create($this, 'TranslatePagesForm', $fields, $actions); return $form; }
/** * Returns all languages with languages already used appearing first. * Called by the SSViewer when rendering the template. */ function LangSelector() { $member = Member::currentUser(); $dropdown = new LanguageDropdownField('LangSelector', 'Language', array(), 'SiteTree', 'Locale-English', singleton('SiteTree')); $dropdown->setValue(Translatable::get_current_locale()); return $dropdown; }
/** * 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); } }
/** * If the record is not shown in the default language, this method * will try to autoselect a master language which is shown alongside * the normal formfields as a readonly representation. * This gives translators a powerful tool for their translation workflow * without leaving the translated page interface. * Translatable also adds a new tab "Translation" which shows existing * translations, as well as a formaction to create new translations based * on a dropdown with available languages. * * @todo This is specific to SiteTree and CMSMain * @todo Implement a special "translation mode" which triggers display of the * readonly fields, so you can translation INTO the "default language" while * seeing readonly fields as well. */ function updateCMSFields(FieldSet &$fields) { // Don't apply these modifications for normal DataObjects - they rely on CMSMain logic if (!$this->owner instanceof SiteTree) { return; } // used in CMSMain->init() to set language state when reading/writing record $fields->push(new HiddenField("Locale", "Locale", $this->owner->Locale)); // Don't allow translation of virtual pages because of data inconsistencies (see #5000) $excludedPageTypes = array('VirtualPage'); foreach ($excludedPageTypes as $excludedPageType) { if (is_a($this->owner, $excludedPageType)) { return; } } $excludeFields = array('ViewerGroups', 'EditorGroups', 'CanViewType', 'CanEditType'); // if a language other than default language is used, we're in "translation mode", // hence have to modify the original fields $creating = false; $baseClass = $this->owner->class; $allFields = $fields->toArray(); while (($p = get_parent_class($baseClass)) != "DataObject") { $baseClass = $p; } // try to get the record in "default language" $originalRecord = $this->owner->getTranslation(Translatable::default_locale()); // if no translation in "default language", fall back to first translation if (!$originalRecord) { $translations = $this->owner->getTranslations(); $originalRecord = $translations ? $translations->First() : null; } $isTranslationMode = $this->owner->Locale != Translatable::default_locale(); // Show a dropdown to create a new translation. // This action is possible both when showing the "default language" // and a translation. Include the current locale (record might not be saved yet). $alreadyTranslatedLocales = $this->getTranslatedLocales(); $alreadyTranslatedLocales[$this->owner->Locale] = $this->owner->Locale; if ($originalRecord && $isTranslationMode) { $originalLangID = Session::get($this->owner->ID . '_originalLangID'); // Remove parent page dropdown $fields->removeByName("ParentType"); $fields->removeByName("ParentID"); $translatableFieldNames = $this->getTranslatableFields(); $allDataFields = $fields->dataFields(); $transformation = new Translatable_Transformation($originalRecord); // 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 ($dataField instanceof HiddenField) { continue; } if (in_array($dataField->Name(), $excludeFields)) { continue; } if (in_array($dataField->Name(), $translatableFieldNames)) { // 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()); } } } elseif ($this->owner->isNew()) { $fields->addFieldsToTab('Root', new Tab(_t('Translatable.TRANSLATIONS', 'Translations'), new LiteralField('SaveBeforeCreatingTranslationNote', sprintf('<p class="message">%s</p>', _t('Translatable.NOTICENEWPAGE', 'Please save this page before creating a translation'))))); } $fields->addFieldsToTab('Root', new Tab('Translations', _t('Translatable.TRANSLATIONS', 'Translations'), new HeaderField('CreateTransHeader', _t('Translatable.CREATE', 'Create new translation'), 2), $langDropdown = new LanguageDropdownField("NewTransLang", _t('Translatable.NEWLANGUAGE', 'New language'), $alreadyTranslatedLocales, 'SiteTree', 'Locale-English', $this->owner), $createButton = new InlineFormAction('createtranslation', _t('Translatable.CREATEBUTTON', 'Create')))); $createButton->includeDefaultJS(false); if ($alreadyTranslatedLocales) { $fields->addFieldToTab('Root.Translations', new HeaderField('ExistingTransHeader', _t('Translatable.EXISTING', 'Existing translations:'), 3)); $existingTransHTML = '<ul>'; foreach ($alreadyTranslatedLocales as $i => $langCode) { $existingTranslation = $this->owner->getTranslation($langCode); if ($existingTranslation) { $existingTransHTML .= sprintf('<li><a href="%s">%s</a></li>', sprintf('admin/show/%d/?locale=%s', $existingTranslation->ID, $langCode), i18n::get_locale_name($langCode)); } } $existingTransHTML .= '</ul>'; $fields->addFieldToTab('Root.Translations', new LiteralField('existingtrans', $existingTransHTML)); } $langDropdown->addExtraClass('languageDropdown'); $createButton->addExtraClass('createTranslationButton'); }
/** * If the record is not shown in the default language, this method * will try to autoselect a master language which is shown alongside * the normal formfields as a readonly representation. * This gives translators a powerful tool for their translation workflow * without leaving the translated page interface. * Translatable also adds a new tab "Translation" which shows existing * translations, as well as a formaction to create new translations based * on a dropdown with available languages. * * This method can be called multiple times on the same FieldList * because it checks which fields have already been added or modified. * * @todo This is specific to SiteTree and CMSMain * @todo Implement a special "translation mode" which triggers display of the * readonly fields, so you can translation INTO the "default language" while * seeing readonly fields as well. */ public function updateCMSFields(FieldList $fields) { $this->addTranslatableFields($fields); // Show a dropdown to create a new translation. // This action is possible both when showing the "default language" // and a translation. Include the current locale (record might not be saved yet). $alreadyTranslatedLocales = $this->getTranslatedLocales(); $alreadyTranslatedLocales[$this->owner->Locale] = $this->owner->Locale; $alreadyTranslatedLocales = array_combine($alreadyTranslatedLocales, $alreadyTranslatedLocales); // Check if fields exist already to avoid adding them twice on repeat invocations $tab = $fields->findOrMakeTab('Root.Translations', _t('Translatable.TRANSLATIONS', 'Translations')); if (!$tab->fieldByName('CreateTransHeader')) { $tab->push(new HeaderField('CreateTransHeader', _t('Translatable.CREATE', 'Create new translation'), 2)); } if (!$tab->fieldByName('NewTransLang') && !$tab->fieldByName('AllTransCreated')) { $langDropdown = LanguageDropdownField::create("NewTransLang", _t('Translatable.NEWLANGUAGE', 'New language'), $alreadyTranslatedLocales, 'SiteTree', 'Locale-English', $this->owner)->addExtraClass('languageDropdown no-change-track'); $tab->push($langDropdown); $canAddLocale = count($langDropdown->getSource()) > 0; if ($canAddLocale) { // Only add create button if new languages are available $tab->push($createButton = InlineFormAction::create('createtranslation', _t('Translatable.CREATEBUTTON', 'Create'))->addExtraClass('createTranslationButton')); $createButton->includeDefaultJS(false); // not fluent API... } else { $tab->removeByName('NewTransLang'); $tab->push(new LiteralField('AllTransCreated', _t('Translatable.ALLCREATED', 'All allowed translations have been created.'))); } } if ($alreadyTranslatedLocales) { if (!$tab->fieldByName('ExistingTransHeader')) { $tab->push(new HeaderField('ExistingTransHeader', _t('Translatable.EXISTING', 'Existing translations'), 3)); if (!$tab->fieldByName('existingtrans')) { $existingTransHTML = '<ul>'; if ($existingTranslations = $this->getTranslations()) { foreach ($existingTranslations as $existingTranslation) { if ($existingTranslation && $existingTranslation->hasMethod('CMSEditLink')) { $existingTransHTML .= sprintf('<li><a href="%s">%s</a></li>', Controller::join_links($existingTranslation->CMSEditLink(), '?Locale=' . $existingTranslation->Locale), i18n::get_locale_name($existingTranslation->Locale)); } } } $existingTransHTML .= '</ul>'; $tab->push(new LiteralField('existingtrans', $existingTransHTML)); } } } }
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); } }
/** * If the record is not shown in the default language, this method * will try to autoselect a master language which is shown alongside * the normal formfields as a readonly representation. * This gives translators a powerful tool for their translation workflow * without leaving the translated page interface. * Translatable also adds a new tab "Translation" which shows existing * translations, as well as a formaction to create new translations based * on a dropdown with available languages. * * @todo This is specific to SiteTree and CMSMain * @todo Implement a special "translation mode" which triggers display of the * readonly fields, so you can translation INTO the "default language" while * seeing readonly fields as well. */ function updateCMSFields(FieldList $fields) { $this->addTranslatableFields($fields); // Show a dropdown to create a new translation. // This action is possible both when showing the "default language" // and a translation. Include the current locale (record might not be saved yet). $alreadyTranslatedLocales = $this->getTranslatedLocales(); $alreadyTranslatedLocales[$this->owner->Locale] = $this->owner->Locale; $alreadyTranslatedLocales = array_combine($alreadyTranslatedLocales, $alreadyTranslatedLocales); $fields->addFieldsToTab('Root', new Tab('Translations', _t('Translatable.TRANSLATIONS', 'Translations'), new HeaderField('CreateTransHeader', _t('Translatable.CREATE', 'Create new translation'), 2), $langDropdown = new LanguageDropdownField("NewTransLang", _t('Translatable.NEWLANGUAGE', 'New language'), $alreadyTranslatedLocales, 'SiteTree', 'Locale-English', $this->owner), $createButton = new InlineFormAction('createtranslation', _t('Translatable.CREATEBUTTON', 'Create')))); $createButton->includeDefaultJS(false); if ($alreadyTranslatedLocales) { $fields->addFieldToTab('Root.Translations', new HeaderField('ExistingTransHeader', _t('Translatable.EXISTING', 'Existing translations:'), 3)); $existingTransHTML = '<ul>'; foreach ($alreadyTranslatedLocales as $langCode) { $existingTranslation = $this->owner->getTranslation($langCode); if ($existingTranslation && $this->owner->ClassName == "SiteConfig") { $existingTransHTML .= sprintf('<li><a href="%s">%s</a></li>', sprintf('%s/?locale=%s', Director::baseURL() . "admin/settings", $langCode), i18n::get_locale_name($langCode)); } else { if ($existingTranslation && $existingTranslation->hasMethod('CMSEditLink')) { $existingTransHTML .= sprintf('<li><a href="%s">%s</a></li>', sprintf('%s/?locale=%s', $existingTranslation->CMSEditLink(), $langCode), i18n::get_locale_name($langCode)); } } } $existingTransHTML .= '</ul>'; $fields->addFieldToTab('Root.Translations', new LiteralField('existingtrans', $existingTransHTML)); } $langDropdown->addExtraClass('languageDropdown no-change-track'); $createButton->addExtraClass('createTranslationButton'); }
/** * Returns all languages with languages already used appearing first. * Called by the SSViewer when rendering the template. */ function LangSelector() { $member = Member::currentUser(); //check to see if the current user can switch langs or not if (Permission::checkMember($member, 'VIEW_LANGS')) { $dropdown = new LanguageDropdownField('LangSelector', 'Language', array(), 'SiteTree', 'Locale-English'); $dropdown->setValue(Translatable::get_current_locale()); return $dropdown; } //user doesn't have permission to switch langs so just show a string displaying current language return i18n::get_locale_name(Translatable::get_current_locale()); }
/** * Creates and returns the language dropdown field * * @param DataObject $dataObj DataObject to get dropdown for * @param string $translatingClass Context class of the LanguageDropdownField * @param string $fieldName Name of the LanguageDropdownField * * @return LanguageDropdownField * * @author Sebastian Diel <*****@*****.**> * @since 21.12.2015 */ public static function prepareLanguageDropdownField($dataObj, $translatingClass = null, $fieldName = 'Locale') { $instance = null; $alreadyTranslatedLocales = array(); if (is_null($translatingClass)) { $translatingClass = $dataObj->ClassName; $instance = $dataObj; } if ($instance) { $alreadyTranslatedLocales = $instance->getTranslatedLocales(); unset($alreadyTranslatedLocales[$instance->Locale]); } $localeDropdown = new LanguageDropdownField($fieldName, _t('SilvercartConfig.TRANSLATION'), $alreadyTranslatedLocales, $translatingClass, 'Locale-Native', $instance); $currentLocale = Translatable::get_current_locale(); $localesWithTitle = $localeDropdown->getSource(); $usedLocalesWithTitle = Translatable::get_existing_content_languages('SiteTree'); $languageList = array(); $usedLanguageList = array(); foreach ($localesWithTitle as $locale => $title) { if (is_array($title)) { foreach ($title as $locale2 => $title2) { $title2 = self::getLanguageDisplayTitle($locale2, $currentLocale); if (array_key_exists($locale2, $usedLocalesWithTitle)) { $usedLanguageList[$locale2] = $title2; unset($languageList[$locale2]); } else { $languageList[$locale2] = $title2; } } } else { $title = self::getLanguageDisplayTitle($locale, $currentLocale); if (array_key_exists($locale, $usedLocalesWithTitle)) { $usedLanguageList[$locale] = $title; unset($languageList[$locale]); } else { $languageList[$locale] = $title; } } } asort($languageList); if (count($usedLanguageList)) { asort($usedLanguageList); $languageList = array(_t('Form.LANGAVAIL', "Available languages") => $usedLanguageList, _t('Form.LANGAOTHER', "Other languages") => $languageList); } $localeDropdown->setSource($languageList); $localeDropdown->setValue($dataObj->Locale); return $localeDropdown; }