TranslatableDataObject: Insanely simple translation
3 Apr
It turns out French-speaking SilverStripe developers are hard to come by. Now that I have contracts with two SilverStripe developers in France, I’m thinking I may have found my niche — my very, very targeted niche.
I was doing work for one my my new clients last week who needed to add translations to his ModelAdmin-managed DataObjects. The Translatable module was failing him. As robust and well-supported as it is, we can identify the limitations of the Translatable module quite easily:
- It works only with SiteTree descendants
- It requires a UI (much like Versioned)
This opens up a need for a simple, code-based translation tool, and what I came up with is TranslatableDataObject.
Usage
MyDataObject.php
static $db = array ( 'Title' => 'Varchar', 'Description' => 'Text' );
_config.php
TranslatableDataObject::set_locales(array(
'en_GB',
'fr_FR',
'it_IT'
));
TranslatableDataObject::register('MyDataObject', array(
'Title',
'Description'
));
Running /dev/build will now add the following fields to MyDataObject:
- Title__en_GB
- Title__fr_FR
- Title__it_IT
- Description__en_GB
- Description__fr_FR
- Description__it_IT
To add the edit fields to the CMS, you have several options.
1. Add all translated fields for all languages to a given tab
foreach($this->getTranslationFields() as $field) {
$f->addFieldToTab("Root.Translations", $field);
}
2. Add all translations for a given field name to a tab
foreach($this->getTranslationFields("Description") as $field) {
$f->addFieldToTab("Root.Descriptions", $field);
}
foreach($this->getTranslationFields("Title") as $field) {
$f->addFieldToTab("Root.Titles", $field);
}
3. Add all fields for a given translation to a tab
foreach($this->getTranslationFields(null, "fr_FR") as $field) {
$f->addFieldToTab("Root.FR", $field);
}
foreach($this->getTranslationFields(null, "en_GB") as $field) {
$f->addFieldToTab("Root.EN", $field);
}
Retrieving the translation on the template
You can use the $T() accessor to retrive the correct field based on the current locale.
$T(Title)
$T(Description)
Limitations
Unlike Translatable, this utility does not create new records for each translation. Translations are added horizontally (i.e. with new columns) rather than vertically (i.e. with new rows). That creates a scalability problem. If you have 10 languages and eight fields that require translation, you’ve just added 80 columns to your table, which, in my understanding of MySQL, will blow things up. Therefore, use this module only for limited translation needs. In my experience, that’s usually all people need, but, then again, I’m in the US, where internationalization is like garnishing a cheeseburger — it’s a nice gesture, but no one really cares.
Getting the code
Umm, it’s on Github.




well… i think it looks really interesting and easy to use. thats all what i need for a module. truly UC’s quality
Great stuff … like always.
*Thumbs Up*
Hi Uncle Cheese!
Great little writeup! Im always impressed of the tidy and simple code you always produce. I, myslef, have also tried to solve the translatable module problems that our web projects face. We are mainly developing ecommerce sites and use our own module for e-commerce sites on Silverstripe. The biggest issue we have regarding languages is that we dont want to translate relations between dataobjects and/or sitetrees. We want same structure, but want to translate single fields only.
I made a small module called multilingual that is based on the multilingual recipe that you, yourself use. Its a bit more “automatic” than yours, but it also lacks the cleanness in code that yours have. Please, you are more than welcome to have a look and maybe contribute? I think one could merge these two “modules” to one great multilingual/translatabledataobject module.
https://github.com/kreationsbyran/multilingual
Thanks for useful module.
I noticed strange behaviour, when I tried to add multilingual fields to DataObject by using decorator (to File class, precisely). Multilingual fields showed up, but they were all in main tab, regardless of what I tried to do in updateCMSFields() function.
Thank you very much for this extension!
Is it possible to use it on a page too?
Thank you
Yes, you can use this on pages, but it doesn’t support translatable URLs.
Hi there Uncle!
I have a question: where should be placed your Translatable.php code in the site?
Thanks a lot
You can put it in your code directory!
Sorry to bother you again, but it seems like designers need more specifications to work with:
MyDataObject.php
That file is placed in mysite/code ?
_config.php
is mysite/_config.php wich i need to add those lines?
TranslatableDataObject.php
where exactly shoud be placed?
in mysite/code ?
thanks for your patience
Eduardo
Yeah, you should never be modifying anything outside your mysite (or themes) directory.
Hi Uncle, using 3.0.3 along Translatable, gives me a blank screen upon rebuild. Followed your instructions closely. I presume your code is for SS3 as it was offered last April.
Is there a way i can detect which language is on?
Like,
Thanks!
Hi UC, thank you for this code, it helps a lot!
I’, using SS2.4 but i can’t get the Option 3 to work.
Trying to create a tab for each language – but it just gives me all fields, even if im using the language filter.
Can you share an example of how that is done?
(It would also be nice to see the complete code for the demo – all the relevant parts put together)
Thank you for sharing all your nice work.