easymultilanguage

Universal and easy multilanguage solution
8 followers

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.

Gitlab link

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 name_en, name_de, description_en, description_de 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

Congratulations ! Now you are awesome =)

Total 8 comments

#18556 report it
Vimark at 2014/11/16 01:27pm
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.

#18554 report it
ahmed.ismail at 2014/11/16 06:10am
Yii2

Hi,

did you test it for yii2.

#18346 report it
Vimark at 2014/10/19 06:04am
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

#18345 report it
ahmed.ismail at 2014/10/19 05:53am
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.

#16903 report it
Vimark at 2014/04/11 05:48am
Re: Editing Issue

Hi,

don't really catch the problem, but did you define desired "admin_routes" in behaviors() in your model ?

#16890 report it
a.abdelaziz.eg at 2014/04/09 08:44am
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 ? :)

#15725 report it
nineinchnick at 2013/12/10 08:40am
public repo

Do you have any public repository for this extension, like on Github?

Leave a comment

Please to leave your comment.

Create extension