Jump to:

3448 Posts in 1062 Topics by 738 members

Data Model Questions

SilverStripe Forums » Data Model Questions » DataObject partial translation

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 577 Views
  • dreadman
    Avatar
    Community Member
    1 Post

    DataObject partial translation Link to this post

    hey there,

    I'm working on a small Google Maps project at the moment. This involves a lot of DataObjects representing markers on my map. Of course by translating the page in other languages the coordinates of my markers stay the same. So I figured out an imo simple way for an universal method for the partial translation of my DataObjects. There are still some small problems, but for now I just want to know what you guys think about it and what could be done better. I'm far away from being a pro, so there will be space for improvements, thats for sure ;)

    Right, here is what I did.

    At first I created an basic object which holds the language and the relationship to the DataObject, that will be partly translatable.

    class TranslatedObjectPart extends DataObject
    {
    static $db = array (
    'Lang' => 'Varchar(10)'
    );

    static $has_one = array (
    'TranslatableDataObject' => 'TranslatableDataObject'
    );

    public function getCMSFields() {
    $allowedLang = Translatable::get_allowed_locales();
    if (empty($allowedLang))
    $allowedLang[] = i18n::default_locale ();
    $langs = array_combine($allowedLang, $allowedLang);

    return new FieldSet(
    new DropdownField('Lang', 'Sprache', $langs)
    );
    }
    }

    Then I have an object, which actually holds one (or possibly more) parts, which can be created in every language you get from Translatable::get_allowed_locales(). The thing I like is that basicly you can translate any data type, not only text. For example you could add a has_one relation to an Image or any other DataObject. I hope you know, what I mean ;)

    class TranslatedText extends TranslatedObjectPart
    {
    static $db = array (
    'Text' => 'Text'
    );

    public function getCMSFields() {
    $f = parent::getCMSFields();
    $f->insertAfter(new TextareaField('Text'), "Lang");
    return $f;
    }
    }

    After that I made a base class for any DataObject, which should be partially translated. This class is very simple, it just deletes all of it8s (partial) translations before it gets deleted.

    class TranslatableDataObject extends DataObject {
    function onBeforeDelete() {
    parent::onBeforeDelete();
    $translations = DataObject::get("TranslatedObjectPart", "TranslatableDataObjectID = $this->ID");
    foreach ($translations->toArray() as $tran)
    $tran->delete();
    }
    }

    Finally, my object which gets translated. I was surprised that you can insert a DataObjectManager into a popup, which itself ist opened by a DOM from a Page, but it works Now I can add translations for the Title, while the rest stays the same. Using TitleInCurrentLang() I get the translation of the Title or the normal Title as fallback.

    class MyDataObject extends TranslatableDataObject
    {
    static $db = array (
    'Title' => 'Text',
    'CenterLat' => 'Double',
    'CenterLng' => 'Double',
       'MapZoom' => 'Int'
    );

    static $has_many = array (
    'TranslatedTitle' => 'TranslatedText'
    );

    public function getCMSFields() {
    return new FieldSet(
    new TextField('Title','Titel'),
    new DataObjectManager(
    $this, // Controller
    'TranslatedTitle', // Source name
    'TranslatedText', // Source class
    array(
    'Text' => 'Titel',
    'Lang' => 'Sprache'
    ),
    'getCMSFields()'
    ),
    new NumericField('CenterLat', 'Breitengrad des Mittepunkts (zB 50.12345)', 0.00000),
    new NumericField('CenterLng', 'Längengrad des Mittepunkts (zB 11.12345)', 0.00000),
    new NumericField('MapZoom', 'Zoomstufe der Karte', 2)
    );
    }

    function TitleInCurrentLang(){
    $lang = Translatable::get_current_locale();
    $title = DataObject::get_one("TranslatedText", "TranslatableDataObjectID = $this->ID AND Lang = '$lang'");
    if ($title)
    return $title->Text;
    return $this->ViewTitle;
    }
    }

    However, there are some little drawbacks with this approach. The popup in the popup is opened at the bottom (not really a problem). And because of the filter in the DataObject::get_one() call inside TitleInCurrentLang() I can only have one TranslatedText per TranslatableDataObject, in more general terms only one object extending TranslatedObjectPart of the same class per TranslatableDataObject. I have some small ideas to work this out...and maybe you guys can give me a push in the right direction? ;)

    Anyway, thats it for now, I'm going home. Merry Chrismas to you all.

    dreadman

    577 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.