multilingual-active-record CActiveRecord subclass for easier handling of multilingual content

  1. Documentation
  2. Change Log
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.
11 2
10 followers
1 189 downloads
Yii Version: 1.1
License: (not set)
Category: Database
Tags:
Developed by: guillemc
Created on: Dec 2, 2009
Last updated: 11 years ago

Downloads

show all