Skip to content

Commit

Permalink
NEW Make it easier to show original values for custom fields.
Browse files Browse the repository at this point in the history
  • Loading branch information
drzax authored and chillu committed Jan 9, 2013
1 parent 9454eb3 commit 44f8180
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 21 deletions.
37 changes: 34 additions & 3 deletions code/model/Translatable.php
Expand Up @@ -213,6 +213,14 @@ class Translatable extends DataExtension implements PermissionProvider {
*/ */
protected static $allowed_locales = null; protected static $allowed_locales = null;


/**
* @var array An array of fields which should be excluded from
* being transformed in the CMS for translated dataobjects. This
* includes some default excludes and any field which has already
* been transformed.
*/
protected $translatableExcludes = null;

/** /**
* Reset static configuration variables to their default values * Reset static configuration variables to their default values
*/ */
Expand Down Expand Up @@ -927,6 +935,14 @@ public function alternateGetByLink($URLSegment, $parentID) {


//-----------------------------------------------------------------------------------------------// //-----------------------------------------------------------------------------------------------//


function applyTranslatableFieldsUpdate($fields, $type) {
if (method_exists($this, $type)) {
$this->$type($fields);
} else {
throw new InvalidArgumentException("Method $type does not exist on object of type ". get_class($this));
}
}

/** /**
* If the record is not shown in the default language, this method * If the record is not shown in the default language, this method
* will try to autoselect a master language which is shown alongside * will try to autoselect a master language which is shown alongside
Expand All @@ -944,6 +960,8 @@ public function alternateGetByLink($URLSegment, $parentID) {
*/ */
function updateCMSFields(FieldList $fields) { function updateCMSFields(FieldList $fields) {
$this->addTranslatableFields($fields); $this->addTranslatableFields($fields);

if ($this->owner->translatableFieldsAdded) return;


// Show a dropdown to create a new translation. // Show a dropdown to create a new translation.
// This action is possible both when showing the "default language" // This action is possible both when showing the "default language"
Expand Down Expand Up @@ -996,13 +1014,17 @@ function updateCMSFields(FieldList $fields) {


$langDropdown->addExtraClass('languageDropdown no-change-track'); $langDropdown->addExtraClass('languageDropdown no-change-track');
$createButton->addExtraClass('createTranslationButton'); $createButton->addExtraClass('createTranslationButton');

$this->owner->translatableFieldsAdded = true;

} }


function updateSettingsFields(&$fields) { function updateSettingsFields(&$fields) {
$this->addTranslatableFields($fields); $this->addTranslatableFields($fields);
} }


protected function addTranslatableFields(&$fields) { protected function addTranslatableFields(&$fields) {

// used in LeftAndMain->init() to set language state when reading/writing record // used in LeftAndMain->init() to set language state when reading/writing record
$fields->push(new HiddenField("Locale", "Locale", $this->owner->Locale)); $fields->push(new HiddenField("Locale", "Locale", $this->owner->Locale));


Expand All @@ -1023,8 +1045,15 @@ protected function addTranslatableFields(&$fields) {
'ViewerGroups', 'ViewerGroups',
'EditorGroups', 'EditorGroups',
'CanViewType', 'CanViewType',
'CanEditType' 'CanEditType',
'NewTransLang',
'createtranslation'
); );

$this->translatableExcludes = ( isset($this->translatableExcludes) && is_array($this->translatableExcludes) )
? array_merge($this->translatableExcludes, $excludeFields)
: $excludeFields;



// if a language other than default language is used, we're in "translation mode", // if a language other than default language is used, we're in "translation mode",
// hence have to modify the original fields // hence have to modify the original fields
Expand Down Expand Up @@ -1059,7 +1088,7 @@ protected function addTranslatableFields(&$fields) {
// (fields are object references, so we can replace them with the translatable CompositeField) // (fields are object references, so we can replace them with the translatable CompositeField)
foreach($allDataFields as $dataField) { foreach($allDataFields as $dataField) {
if($dataField instanceof HiddenField) continue; if($dataField instanceof HiddenField) continue;
if(in_array($dataField->getName(), $excludeFields)) continue; if(in_array($dataField->getName(), $this->translatableExcludes)) continue;


if(in_array($dataField->getName(), $translatableFieldNames)) { if(in_array($dataField->getName(), $translatableFieldNames)) {
// if the field is translatable, perform transformation // if the field is translatable, perform transformation
Expand All @@ -1068,6 +1097,8 @@ protected function addTranslatableFields(&$fields) {
// else field shouldn't be editable in translation-mode, make readonly // else field shouldn't be editable in translation-mode, make readonly
$fields->replaceField($dataField->getName(), $dataField->performReadonlyTransformation()); $fields->replaceField($dataField->getName(), $dataField->performReadonlyTransformation());
} }
$this->translatableExcludes[] = $dataField->getName();
$this->translatableExcludes[] = $dataField->getName() . '_original';
} }


} elseif($this->owner->isNew()) { } elseif($this->owner->isNew()) {
Expand All @@ -1081,7 +1112,7 @@ protected function addTranslatableFields(&$fields) {
) )
) )
); );
} }
} }


/** /**
Expand Down
37 changes: 20 additions & 17 deletions docs/en/index.md
Expand Up @@ -197,10 +197,10 @@ Keep in mind that the `[api:Translatable]` extension currently doesn't support t
translated - all custom properties will automatically be fetched from their translated record on the database. This means translated - all custom properties will automatically be fetched from their translated record on the database. This means
you don't have to explicitly mark any custom properties as being translatable. you don't have to explicitly mark any custom properties as being translatable.


The `[api:Translatable]` decorator applies only to the getCMSFields() method on DataObject or SiteTree, not to any fields The `[api:Translatable]` decorator applies only to the getCMSFields() method on DataObject or SiteTree and the getSettingsFields()
added in overloaded getCMSFields() implementations. See Translatable->updateCMSFields() for details. By default, custom on SiteTree, not to any fields added in overloaded getCMSFields() implementations. See Translatable->updateCMSFields() for details.
fields in the CMS won't show an original readonly value on a translated record, although they will save correctly. You can By default, custom fields in the CMS won't show an original readonly value on a translated record, although they will save correctly. You can
attach this behaviour to custom fields by using Translatable_Transformation as shown below. attach this behaviour to custom fields by calling a helper function from your getCMSFields() and getSettingsFields() functions.


:::php :::php
class Page extends SiteTree { class Page extends SiteTree {
Expand All @@ -214,24 +214,27 @@ attach this behaviour to custom fields by using Translatable_Transformation as s


// Add fields as usual // Add fields as usual
$additionalField = new TextField('AdditionalProperty'); $additionalField = new TextField('AdditionalProperty');
$fields->addFieldToTab('Root.Content.Main', $additionalField); $fields->addFieldToTab('Root.Main', $additionalField);
// If a translation exists, exchange them with // Apply Translatable modifications
// original/translation field pairs $this->applyTranslatableFieldsUpdate($fields, 'updateCMSFields');
$translation = $this->getTranslation(Translatable::default_locale());
if($translation && $this->Locale != Translatable::default_locale()) {
$transformation = new Translatable_Transformation($translation);
$fields->replaceField(
'AdditionalProperty',
$transformation->transformFormField($additionalField)
);
}


return $fields; return $fields;
} }
}


function getSettingsFields() {
$fields = parent::getSettingsFields();

// Add fields as usual
$additionalField = new TextField('AdditionalProperty');
$fields->addFieldToTab('Root.Main', $additionalField);
// Apply Translatable modifications
$this->applyTranslatableFieldsUpdate($fields, 'updateSettingsFields');

return $fields;
}
}




### Translating the Homepage ### Translating the Homepage
Expand Down
30 changes: 29 additions & 1 deletion tests/unit/TranslatableTest.php
Expand Up @@ -220,7 +220,8 @@ function testTranslationCantHaveSameURLSegmentAcrossLanguages() {
} }


function testUpdateCMSFieldsOnSiteTree() { function testUpdateCMSFieldsOnSiteTree() {
$pageOrigLang = $this->objFromFixture('Page', 'testpage_en'); $pageOrigLang = new TranslatableTest_Page();
$pageOrigLang->write();


// first test with default language // first test with default language
$fields = $pageOrigLang->getCMSFields(); $fields = $pageOrigLang->getCMSFields();
Expand All @@ -233,6 +234,11 @@ function testUpdateCMSFieldsOnSiteTree() {
$fields->dataFieldByName('Title_original'), $fields->dataFieldByName('Title_original'),
'Translatable doesnt modify fields if called in default language (e.g. "non-translation mode")' 'Translatable doesnt modify fields if called in default language (e.g. "non-translation mode")'
); );
$this->assertInstanceOf(
'TextField',
$fields->dataFieldByName('TranslatableProperty'),
'Has custom field'
);


// then in "translation mode" // then in "translation mode"
$pageTranslated = $pageOrigLang->createTranslation('fr_FR'); $pageTranslated = $pageOrigLang->createTranslation('fr_FR');
Expand All @@ -248,6 +254,16 @@ function testUpdateCMSFieldsOnSiteTree() {
$fields->dataFieldByName('Title_original'), $fields->dataFieldByName('Title_original'),
'Translatable adds the original value as a ReadonlyField in "translation mode"' 'Translatable adds the original value as a ReadonlyField in "translation mode"'
); );
$this->assertInstanceOf(
'ReadonlyField',
$fields->dataFieldByName('TranslatableProperty_original'),
'Retains original custom field'
);
$this->assertInstanceOf(
'TextField',
$fields->dataFieldByName('TranslatableProperty'),
'Adds custom fields as ReadonlyField'
);


} }


Expand Down Expand Up @@ -990,6 +1006,18 @@ class TranslatableTest_Page extends Page implements TestOnly {
static $db = array( static $db = array(
'TranslatableProperty' => 'Text' 'TranslatableProperty' => 'Text'
); );

function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab(
'Root.Main',
new TextField('TranslatableProperty')
);

$this->applyTranslatableFieldsUpdate($fields, 'updateCMSFields');

return $fields;
}
} }


DataObject::add_extension('TranslatableTest_DataObject', 'TranslatableTest_Extension'); DataObject::add_extension('TranslatableTest_DataObject', 'TranslatableTest_Extension');
Expand Down

0 comments on commit 44f8180

Please sign in to comment.