/** * 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. * * @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'); }
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); } }
/** * Adds a translation section * * @param FieldList $fields The FieldList * * @return void * * @author Sebastian Diel <*****@*****.**> * @since 04.04.2013 */ public function updateCMSFields(FieldList $fields) { $this->getCMSFieldsIsCalled = true; $fields->findOrMakeTab('Root.SEO')->setTitle($this->owner->fieldLabel('SeoTab')); $fields->findOrMakeTab('Root.SocialMedia')->setTitle($this->owner->fieldLabel('SocialMediaTab')); $fields->findOrMakeTab('Root.Translations')->setTitle($this->owner->fieldLabel('TranslationsTab')); $googleWebmasterCodeField = new TextField('GoogleWebmasterCode', $this->owner->fieldLabel('GoogleWebmasterCode')); $googleAnalyticsTrackingCodeField = new TextareaField('GoogleAnalyticsTrackingCode', $this->owner->fieldLabel('GoogleAnalyticsTrackingCode')); $googleConversionTrackingCodeField = new TextareaField('GoogleConversionTrackingCode', $this->owner->fieldLabel('GoogleConversionTrackingCode')); $piwikTrackingCodeField = new TextareaField('PiwikTrackingCode', $this->owner->fieldLabel('PiwikTrackingCode')); $fields->addFieldToTab('Root.SEO', $googleWebmasterCodeField); $fields->addFieldToTab('Root.SEO', $googleAnalyticsTrackingCodeField); $fields->addFieldToTab('Root.SEO', $googleConversionTrackingCodeField); $fields->addFieldToTab('Root.SEO', $piwikTrackingCodeField); $facebookLinkField = new TextField('FacebookLink', $this->owner->fieldLabel('FacebookLink')); $twitterLinkField = new TextField('TwitterLink', $this->owner->fieldLabel('TwitterLink')); $xingLinkField = new TextField('XingLink', $this->owner->fieldLabel('XingLink')); $fields->addFieldToTab('Root.SocialMedia', $facebookLinkField); $fields->addFieldToTab('Root.SocialMedia', $twitterLinkField); $fields->addFieldToTab('Root.SocialMedia', $xingLinkField); $translatable = new Translatable(); $translatable->setOwner($this->owner); $translatable->updateCMSFields($fields); $localeField = new TextField('CurrentLocale', $this->owner->fieldLabel('CurrentLocale'), i18n::get_locale_name($this->owner->Locale)); $createButton = new InlineFormAction('createsitetreetranslation', $this->owner->fieldLabel('createsitetreetranslation')); $publishButton = new InlineFormAction('publishsitetree', $this->owner->fieldLabel('publishsitetree')); $localeField->setReadonly(true); $localeField->setDisabled(true); $createButton->setRightTitle($this->owner->fieldLabel('createsitetreetranslationDesc')); $createButton->includeDefaultJS(false); $createButton->addExtraClass('createTranslationButton'); $publishButton->includeDefaultJS(false); $publishButton->addExtraClass('createTranslationButton'); $fields->addFieldToTab('Root.Translations', $localeField, 'CreateTransHeader'); $fields->addFieldToTab('Root.Translations', $createButton, 'createtranslation'); $fields->addFieldToTab('Root.Translations', $publishButton, 'createtranslation'); $fields->removeByName('createtranslation'); $this->getCMSFieldsForSilvercart($fields); }