nedarta / yii2-translated-behavior
This extension allows you to quickly and simple enough to add translations for any ActiveRecord models.
Package info
github.com/nedarta/yii2-translated-behavior
Type:yii2-extension
pkg:composer/nedarta/yii2-translated-behavior
Requires
- php: ^8.0
- yiisoft/yii2: ^2.0
Requires (Dev)
- phpunit/phpunit: ^9.5
- roave/security-advisories: dev-master
This package is auto-updated.
Last update: 2026-03-10 12:43:18 UTC
README
The Translated Behavior is a Yii2 extension for ActiveRecord models, that will help you add the possibility of transferring any entity.
You can see DEMO
Note
This is a fork of the original work by Alexey Loban (lav45). This version includes several modernizations and improvements for PHP 8.0+.
Changes and Improvements (nedarta version)
- PHP 8.0+ Modernization: Added strict type hints for properties, parameters, and return types across the codebase.
- Namespace Rebranding: Refactored to the
nedarta\translatenamespace. - Automatic Language Negotiation: Integrated a new
LanguageNegotiatorandBootstrapclass for automatic, model-driven I18N setup. - Improved Lifecycle Management: Fixed a critical bug where
updated_at(and other owner timestamp attributes) were not updating when only translation fields were changed. - Enhanced Attribute Access: Added
getOldAttribute()andgetOldAttributes()support for translated fields within theTranslatedTrait. - Modernized Test Suite: Completely overhauled the test suite for compatibility with PHPUnit 9.5+, including a custom database helper set that replaces the discontinued
dbunit.
Installation
The preferred way to install this extension through composer.
You can set the console
$ composer require "lav45/yii2-translated-behavior:1.4.*"
or add
"lav45/yii2-translated-behavior": "1.4.*"
in require section in composer.json file.
Settings
First you have to move all the attributes that are required for translation in a separate table. For example, imagine that we want to save the translation of the title and description of your post being. Your table schema should be brought to the following form:
+--------------+ +--------------+ +-------------------+
| post | | post | | post_lang |
+--------------+ +--------------+ +-------------------+
| id | | id | | post_id |
| title | ---> | created_at | + | lang_id |
| description | | updated_at | | title |
| updated_at | +--------------+ | description |
| created_at | +-------------------+
+--------------+
After you change the table schema, we now need to determine the ratio of our ActiveRecord objects and adding behavior:
Post
use yii\db\ActiveRecord; use nedarta\translate\TranslatedTrait; use nedarta\translate\TranslatedBehavior; /** * ... * @property string $title * @property string $description */ class Post extends ActiveRecord { use TranslatedTrait; public function rules() { return [ // ... [['title'], 'required'], [['title'], 'string', 'max' => 128], [['description'], 'required'], [['description'], 'string'], ]; } public function behaviors() { return [ [ 'class' => TranslatedBehavior::class, 'translateRelation' => 'postLangs', // Specify the name of the connection that will store transfers // 'languageAttribute' => 'lang_id' // post_lang field from the table that will store the target language 'translateAttributes' => [ 'title', 'description', ], // list of owner attributes to be changed when translation is changed. // This is useful to trigger TimestampBehavior on the owner model. 'updateOwnerAttributes' => ['updated_at'], ] ]; } public function attributeLabels() { return [ // ... 'title' => 'Title', 'description' => 'Description', ]; } public function getPostLangs() { return $this->hasMany(PostLang::className(), ['post_id' => 'id']); } }
Language model
migrate
migrate/m151220_112320_lang.php
Apply with the console command:
~$ yii migrate/up --migrationPath=vendor/lav45/yii2-translated-behavior/migrate
Lang ActiveRecord model cite completely
\nedarta\translate\models\Lang
Using
Backend
backend/config/bootstrap.php
Yii::$container->set('nedarta\translate\TranslatedBehavior', [ 'language' => isset($_GET['lang_id']) ? $_GET['lang_id'] : null ]);
backend/controllers/PostController.php
namespace backend\controllers; use yii\web\Controller; use yii\data\ActiveDataProvider; use common\models\Post; use common\models\Lang; class PostController extends Controller { public function actionIndex() { $dataProvider = new ActiveDataProvider([ 'query' => Post::find() ->with([ 'currentTranslate', // loadabing data associated with the current translation 'hasTranslate' // need to display the status was translated page ]), ]); return $this->render('index', [ 'dataProvider' => $dataProvider, 'langList' => Lang::getList(), ]); } // ... }
backend/view/post/index.php
<?= GridView::widget([ 'dataProvider' => $dataProvider, 'columns' => [ [ 'class' => 'nedarta\translate\grid\ActionColumn', 'languages' => $langList, ], [ 'class' => 'yii\grid\ActionColumn', 'template' => '{delete}' ], ], ]); ?>
As a result, after the creation of a new page will get a few buttons to edit the content in different languages
So you can get the current language of the model
/** * @var $this yii\web\View * @var $model common\models\Page */ $this->title = 'Create Post ( ' . $model->language . ' )';
Frontend
frontend/config/main.php
use nedarta\translate\models\Lang; return [ 'components' => [ 'urlManager' => [ 'class' => 'nedarta\translate\web\UrlManager', 'enablePrettyUrl' => true, 'showScriptName' => false, 'rules' => [ [ 'class' => 'yii\web\UrlRule', // If there is no need to substitute the language, you can use the base class 'pattern' => '', 'route' => 'post/index', ], [ 'pattern' => '<_lang:' . Lang::PATTERN . '>/<id:\d+>', 'route' => 'post/view', ], [ 'pattern' => '<_lang:' . Lang::PATTERN . '>', 'route' => 'post/index', ] ], ], ], ];
frontend/controllers/PostController.php
namespace frontend\controllers; use yii\web\Controller; use common\models\Post; use nedarta\translate\web\LanguageNegotiator; class PostController extends Controller { public function behaviors() { return [ [ // LanguageNegotiator will be determined from a URL or browser language settings and install it in // Yii::$app->language, which uses the class TranslatedBehavior as language translation // It automatically uses locales from the Lang model. 'class' => LanguageNegotiator::class, ], ]; } }
Automatic Bootstrap
The extension can automatically register the LanguageNegotiator for all controllers.
This is handled by the nedarta\translate\Bootstrap class, which is registered in composer.json.
If you are using a custom setup or need to manually register it, you can add it to your configuration:
'bootstrap' => [ // ... 'nedarta\translate\Bootstrap', ],
License
yii2-translated-behavior it is available under a BSD 3-Clause License. Detailed information can be found in the LICENSE.md.
