EasyMultiLanguage ¶
This crazy stuff helps you to implement mulitlanguage to your application almost without code modifications and pain in the ass. Sit back, relax and enjoy. The magic begins.
Intro ¶
Imagine that you have a huuuuge application with a lot of logic and views. And one day you need to implement multilanguage system to your existing models. Do you wanna some candy behavior that do all magic ? Welcome my little fella, this is what you need.
How the hell it works ? ¶
This behavor replace all desired attributes with current language translations. (Except admin routes, where you need all languages as they are, for editing)
Let's say you have default language "ru". And you have this book:
$book->name = "Снег";
$book->name_en = "Snow"; // name_en automatically added by behavior
Now if you'll change language to "en", You book will looks like this:
$book->name = "Snow";
$book->name_en = "Snow"; // name_en automatically added by behavior
Installation ¶
1) Put this piece of happines in your extensions folder ¶
2) Database ¶
Import "EasyMultiLanguage/data/translations.sql"
3) In your config ¶
...
'import'=>array(
...
'ext.EasyMultiLanguage.*',
...
),
...
'urlManager'=>array(
'class'=>'EMUrlManager', // <---- You need this line, but other lines might save you too
'showScriptName'=>false,
'urlFormat'=>'path',
'rules'=>array(
'<_c:\w+>/<id:\d+>'=>'<_c>/view',
'<_c:\w+>/<_a:\w+>/<id:\d+>'=>'<_c>/<_a>',
'<_c:\w+>/<_a:\w+>'=>'<_c>/<_a>',
'<_m:\w+>/<_c:\w+>/<_a:\w+>'=>'<_m>/<_c>/<_a>',
'<_m:\w+>/<_c:\w+>/<_a:\w+>/<id:\d+>'=>'<_m>/<_c>/<_a>',
),
),
...
'params'=>array(
'languages'=>array(
'ru' => 'Русский',
'en' => 'English',
'de' => 'Deutsche',
),
'default_language' => 'ru',
),
4) In your Model ¶
Lets say you have model Book with attributes name, author, description and status And you want to have name and description in English and Deutsche, while your default language is Russian
<?php
class Book extends CActiveRecord
{
/**
* __set
*
* Rewrite default setter, so we can dynamically add
* new virtual attribtues such as name_en, name_de etc.
*
* @param string $name
* @param string $value
*/
public function __set($name, $value)
{
if (EMHelper::WinnieThePooh($name, $this->behaviors()))
$this->{$name} = $value;
else
parent::__set($name, $value);
}
/**
* behaviors
*
* @return array
*/
public function behaviors()
{
return array(
'EasyMultiLanguage'=>array(
'class' => 'ext.EasyMultiLanguage.EasyMultiLanguageBehavior',
'translated_attributes' => array('name', 'description'),
'languages' => Yii::app()->params['languages'],
'default_language' => Yii::app()->params['default_language'],
'admin_routes' => array('book/admin', 'book/update', 'book/create'),
'translations_table' => 'translations',
),
);
}
....
}
5) In your base Controller ("/components/Controller.php") ¶
<?php
class Controller extends CController
{
/**
* init
*
* Something happening here
*/
public function init()
{
EMHelper::catchLanguage();
parent::init();
}
}
Usage ¶
1) In your view file ("views/book/_form") ¶
You need this only for editing form
You have new virtual attributes _nameen, _namede, _descriptionen, _descriptionde You can treat them as normal attributes.
Also nice Html helper is provided. It will create tab switcher between different language inputs.
There are 2 options:
- You have Twitter Bootstrap
- You don't have it
If you have Twitter Bootstrap
<?php echo EMHelper::megaOgogo($model, $attribute, $htmlOptions = array(), $fieldType = 'textField'); ?>
textField
<div class='control-group'>
<?php echo $form->labelEx($model,'name', array('class'=>'control-label')); ?>
<div class='controls'>
<?php echo EMHelper::megaOgogo($model, 'name', array('class'=>'span25')); ?>
<?php echo $form->error($model,'name'); ?>
</div>
</div>
textArea
<div class='control-group'>
<?php echo $form->labelEx($model,'description', array('class'=>'control-label')); ?>
<div class='controls'>
<?php echo EMHelper::megaOgogo($model, 'description', array('class'=>'span25', 'rows'=>7), 'textArea'); ?>
<?php echo $form->error($model,'description'); ?>
</div>
</div>
If you don't have Twitter Bootstrap
<?php echo EMHelper::multiInput($model, $attribute, $htmlOptions = array(), $fieldType = 'textField'); ?>
Like
<?php echo $form->labelEx($model,'name'); ?>
<?php echo EMHelper::multiInput($model, 'name'); ?>
<?php echo $form->error($model,'name'); ?>
2) Now put somewhere in main layout this LanguageSelectorWidget ¶
<?php $this->widget('ext.EasyMultiLanguage.widgets.LanguageSelectorWidget', array(
'style' => 'dropDown', // "dropDown" or "inline". Optional. Default is "dropDown"
'cssClass' => 'bla-bla', // Optional. Additional css class for selector.
)); ?>
Perfomance ¶
In order to keep your perfomance bright and shiny, it's recommended to use different translation tables for different models if they have a lot of records. And if you know, that all attributes of your model will be varchar, then change value type from mediumtext to varchar in "translations" table
public repo
Do you have any public repository for this extension, like on Github?
Re: public repo
Yes, https://gitlab.com/yii-modules/easymultilanguage/tree/master
Editing Issue
Firstly, I'd like to thank you for this great extension.
I used this great extension in an application, but I faced a problem that when editing a post in admin area, it loaded with only the default language data, so when selecting a tab of another language for specific field it displayed with no data. Do you have a solution for that ? :)
Re: Editing Issue
Hi,
don't really catch the problem, but did you define desired "admin_routes" in behaviors() in your model ?
While update outside form
Hi, many thanks for your extension, I'm using it many times.
A strange problem occurs when i load a model and save it in case that the current language isn't the default language.
$article = Article::model()->findByAttributes(array('slug'=>$slug)); $article->num_reads++; $article->save();
The current language attributes are deleted and saved in the default language attributes.
this is a big problem for me. I hope your help, thanks.
Re: While update outside form
Hi, you have to define your route where you save model in 'admin_routes'.
Because in all over routes, value of the translated attribute will be replaced with translation. And after save, you'll be saving model with translated value
Yii2
Hi,
did you test it for yii2.
Re: Yii2
Hi. I have it for Yii2
https://github.com/webvimark/multilanguage
But keep in mind, it's lacking proper documentation and may be (and will be) changed without notice because it's not final and not fully tested version.
Although it's stable enough for real projects and you can use. But you should lock this composer package after you install it.
'CException' with message 'Property "XXX.id" is not defined.'
Replace $this->owner->id to $this->owner->primaryKey in EasyMultil..Behaviour.php to allow different primary key name other than id
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.