Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Data Model Questions /

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

Translate / Translatable and Dataobjects


Go to End


13 Posts   8934 Views

Avatar
Stefdv

Community Member, 110 Posts

26 September 2011 at 8:29am

Hello,

Can't seem to find any recent posts about translatable dataobjects. I have about 300 DataObjects ( and growing), they only need one field to be translated ('Discription').

I've tried TranslatableModelAdmin (TMA) and...well...yes it works...But it will create every object again in the second language, now that wouldn't be a problem for 'simple' DO's. My DO's have relations to other DO's which are created by selecting them in an optionsfield, the way TMA handles it i'll have to create the relations for both languages every time i create an object.

It's not very user friendly for a content administrator...

In fact i don't need to translate every field of the object ( So i only have to pick there relations to other objects once ) i only need to translate the discription of the Object. And then in my template i'll need a way to replace the discription field according to the users locale.

Avatar
swaiba

Forum Moderator, 1899 Posts

1 October 2011 at 12:25am

Hi Stefdv,

I've recently gone ahead and done my original plan (that didn't include translatable model admin) and it looks like this...

class MyObject extends DataObject {
	static $db = array(
		'Name' 					=> 'Text',
	);
...
	static $has_many = array(
		'MyObjectLocaleData'	=> 'MyObjectLocaleData',
	);
...
	function LocalizedName() {
		if (USING TRANSLATEABLE) {
			$strLocale = Session::get('Locale'); //I store the local in the session on page init.php for ajax and other stuff
			$dosInfo = DataObject::Get('MyObjectLocaleData',"MyObjectID=".$this->ID." AND Locale='".$strLocale."'");
			if ($dosInfo->TotalItems() > 0) {
				return $dosInfo->First()->Name;
			}
		}
		return $this->Name;
	}
}

class MyObjectLocaleData extends DataObject {
	static $db = array(
		'Name' 		=> 'Varchar',
		'Locale'	=> 'Varchar',
	);

	static $has_one = array(
		'MyObject'	=> 'MyObject',
	);

	public static $summary_fields = array (
		'LocaleText'		=> 'LocaleText',
		'Name' 				=> 'Name',
	);

	static $casting = array(
		"LocaleText" 		=> "Text"
	);
	public function LocaleText(){return i18n::get_locale_name($this->Locale);}

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

		$localemap = explode(",",Config::Get('translatable_locales'));//you will need to update I have a config layer storing my locales (don't ask)
		$map = array();
		if (count($localemap)) foreach ($localemap as $locale) {
			$map[$locale] = i18n::get_locale_name($locale);
		}

		$fields->replaceField('Description', new SimpleTinyMCEField('Description'));
		$fields->replaceField('Locale', new DropdownField('Locale','Locale',$map));

		return $fields;
	}
}

then I place $LocalizedName in templates or use it $obj->LocalizedName() instead of name.

it's not the best, but hope it helps...

Barry

Avatar
Stefdv

Community Member, 110 Posts

1 October 2011 at 8:44pm

Edited: 01/10/2011 8:48pm

Swaiba,

We meet again ;).

I did solve the problem in a different way. however when i look at your solution i'm afraid i missed some - important ? - parts.

I've created an extra DO 'LocaleDiscription'

class LocaleDiscription extends DataObject {

    public static $db = array(	'Language' 		=> 	"i18nEnum('Nederlands, Engels','Nederlands')", 
								'Discription' 	=> 	'HTMLText'	
								);
								
	public static $has_one = array( 'Dog'	=>	'Dog' );
	

    function getCMSFields() {
        $fields = parent::getCMSFields();
		$fields->removeByName('Discription');
		$fields->addFieldToTab('Root.Main', new SimpleTinyMCEField('Discription','Discription'));
		//$fields = new HasOneDataObjectManager($this,'Dog', 'Dog');
        return $fields;
    }
 function getCurrentLanguage() { 
      return Translatable::get_current_locale(); 
   }
   
   function getDutchDiscription() {
	   $dutchdiscription = DataObject::get_one('LocaleDiscription', "DogID = " . $this->DogID);
		return $dutchdiscription;
   }
   
      function getEnglishDiscription() {
	   $Englishdiscription = DataObject::get('LocaleDiscription', "\"DogID\" = " . $this->DogID);
		return $Englishdiscription;
   }

}

Then in my original DO i replaced my 'discription field' with a has_many LocaleDiscriptions relation.

In my templates i just use the functions ( see above code ) to determine what language the page is vieuwed in and show the right discription.

It works perfect, but do i miss something or do you think your solution is more userfriendly?
I really hope they will make this better in SS3...

-------- Edit after reading my post and yours again ----

Seems like your doing the samething, the difference is in our functions. What's the reason for storing this in a session? To be honest i don't really get your function, that's why my solution isn't really something new, since it builds on the same techniques we use everywere.

Avatar
swaiba

Forum Moderator, 1899 Posts

2 October 2011 at 3:34am

The reason I use the session is because some of my pages (implementing HiddenClass) are not translated within the CMS and then on those pages I do a bunch of AJAX requests... the simplest method for noting and providing a smooth multilingual experience was to store the locale on normal pages when changed and then this provides the info on the other pages which don't have it set.

My functions are a little more generic as the localised description function seems to combine your two function for english and dutch - plus allow for any number of languages.

Avatar
Stefdv

Community Member, 110 Posts

2 October 2011 at 7:55pm

Swaiba,

tx for the explanation. I get your point. The way i do it only allows the languages i declare in my functions, which is fine for me since i know i'll only use those two. I will try your solution in time.

Go to Top