NOTE (2012-03-25) ¶
Please check fredpeak's multilingual behavior, which implements many of the ideas discussed in the Multilingual models thread into a nice behavior!
NOTE (2011-11-24) ¶
This extension is obsolete, and not maintained anymore. I'm now using a behavior to accomplish the same thing, please see this post.
Introduction ¶
This extension simplifies the handling of multilingual content stored in the database.
It assumes that you use two tables for your content (one for the main content and a second one for the translations) with a one-to-many relationship between them.
Resources ¶
Documentation ¶
Requirements ¶
- Yii 1.1 or above
Installation ¶
- Extract the release file under
protected/extensions
Usage example: ¶
We have a table (and corresponding AR model) Post, with fields id, title, content. The title and content fields store values in the primary or default language of the application.
Then we have a table (and AR model) PostLang, with fields id, postId, lang, title, content, which stores title and content in additional languages.
First we make the Post model extend from MultilingualActiveRecord instead of CActiveRecord, and configure it (language codes ideally would come from application params rather than be hardcoded):
class Post extends MultilingualActiveRecord
{
//primary language
public function primaryLang() {
return 'en';
}
//additional languages found in the translations table
public function languages() {
return array('es', 'fr');
}
//attributes to look for in the translations table
public function localizedAttributes() {
return array('title','content');
}
...
}
NOTE: We could also override langField() (which defaults to 'lang'), langForeignKey() and langClassName() (which in the Post example default to 'postId' and 'PostLang').
OK, now with the Post model we can use 2 new methods: localized() and multilingual().
The localized() method is meant to be used on the frontend. What it does is overwrite the localized attributes (title and content) with their translations, using the language currently set in the application.
//inside post controller, list action
$posts = Post::model()->localized()->findAll($criteria);
//inside post controller, show action
$post = Post::model()->localized()->findbyPk($id);
The multilingual() method is meant to be used on the backend, when you require access to the model together with its localized attributes in all languages:
//inside controller, edit action
$post = Post::model()->multilingual()->findbyPk($id);
It allows you to get and set the localized attributes in all languages as if they were part of the model itself, using the suffix _language, like this:
//inside view
echo $post->title_es;
echo $post->title_fr;
echo CHtml::activeTextField($post,'title_es');
echo CHtml::activeTextField($post,'title_fr');
After you call the save() method on the model, the translations will also be saved to the translations table.
Remember to include these new attributes when overriding the model's rules() method, otherwise they will not be assigned:
public function rules()
{
$rules = array(
array('title', 'required'),
array('title', 'length', 'max'=>128),
array('content', 'safe'),
);
foreach ($this->languages() as $l) {
$rules[] = array('title_'.$l, 'length', 'max'=>128);
$rules[] = array('content_'.$l, 'safe');
}
return $rules;
}
Change Log ¶
December 2, 2009 ¶
- Initial release.
not working..
The method on line 114 should be..
public function langClassName() {
return get_class($this);
}
But even then I get:
Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 35 bytes) in /var/www/html/flipbook/framework/collections/CList.php on line 150
Nice one
This Extension saved me mutch time.
I Combined it with a CDataProvider. Maybe you could inegrate that one in your next release. I Post the Details in the Forum.
Thanks again
thanks for this great extention.
i am kinda new to yii. does this extension work with the following?
$post::model->with('messages')->findAll()
post and messages being multilingual.
thanks
great job!
thanks a lot..
Works great
Managed to get it working quite nicely. :) Well done guillemc.
Thanks! a little note
Thanks for the effort, firstly.
Isn't it preferred to save all the translations in one 'translations' table, which will be categorized by tables, and contain fields such as 'id', 'table', 'lang_id', 'key', 'value'?
Seems to me that it is a bit messy to create so many duplicate tables just for translations...
What's you opinion?
i18n database scheme.
There are many ways to store i18n data in your database.
I personally prefer the variant with two tables per model, because the joins are simple and it's a good way to keep the model data together.
In the scheme this extension uses you get double columns for every language fields, which adds redundant work when adding or modifying language columns. A common way to solve this is to remove the language fields from the Model table, so they only exist in the ModelLanguage table. Example: Table Post (post_id, author_id, enabled), Table PostLanguage (post_id, language, title, subtitle, content).
I am modifying (and documenting) this extension to do just that, and will post the results when completed.
how to
How to use this extension with related models?
For example:
Questions model has relation:
public function relations() { // NOTE: you may need to adjust the relation name and the related // class name for the relations automatically generated below. return array( 'answers' => array(self::MANY_MANY, 'Answers', 'tbl_questions_has_tbl_answers(tbl_questions_id, tbl_answers_id)') ); }
I want to get both of them translation.
Default language lang=en. In this situation it works prefect.
But when i change site language with lang=ru, it returns only Question translation! Does anybody know how to solve this problem?
Yii::app()->language = $_GET['lang']; $model = Questions::model()->localized()->findByPk('1'); // Question echo 'Question: ' . $model->title . '<br/>'; // Answers foreach($model->answers as $value) { echo $value->title . '<br/>'; }
multilingualbehaviour - update problem
Hi guillemc!
I've been using your MultilingualBehaviour, and it works fine int he translate displaying, and creating a new record, but I get an error when trying to update the records..
http://www.yiiframework.com/forum/index.php?/topic/4888-multilingual-models/page__st__40__gopid__135722#entry135722
I wrote also the question in the forum line where you explained the behavior.
Thank you in advance!!
Diana.
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.