Modeling Multilingual Attributes in Laravel, a nice approach

what if we use a field and set its content to change dynamically depending on the language of the user, and replacing the previous example with the following simple line: -$title = $category->title;Let’s say we have Category Model and it has title_ar and title_en fields, we will build trait so when we call $category->title it will return the title_ar or title_en depending on the user’s language.

As a Laravel developer, I think you should know PHP Magic Methods, especially __get magic method which we will rely on in this tutorial.

Laravel uses __get to handle model fields and mutators so it will get fields values from the database without your intervention.

Now I think you should know what is the requirement and have an idea of how to build it, let’s go!!!Firstly, we will create the Publication Model and its migration in your Laravel project.

php artisan make:model Category -mNote that we have added title_ar, title_en fields in the Category migration file, So it will be like the following code.

<?phpuse IlluminateSupportFacadesSchema;use IlluminateDatabaseSchemaBlueprint;use IlluminateDatabaseMigrationsMigration;class CreateCategoriesTable extends Migration{ /** * Run the migrations.

* * @return void */ public function up() { Schema::create('categories', function (Blueprint $table) { $table->increments('id'); $table->string('title_ar'); $table->string('title_en'); $table->timestamps(); }); }/** * Reverse the migrations.

* * @return void */ public function down() { Schema::dropIfExists('categories'); }}Now in the model, We will define $multi_lang array attribute, which will have the attributes without the language suffix, and uses MultiLanguage Trait “use MultiLanguage;” which we will define it in the next step.

<?phpnamespace App;use AppTraitsMultiLanguage;use IlluminateDatabaseEloquentModel;class Category extends Model{ use MultiLanguage;protected $fillable = [ 'title_en', 'title_ar', ]; /** * This array will have the attributes which you want it to support multi languages */ protected $multi_lang = [ 'title', ];}What now!!.we will define a new trait which has the simple magic code, this trait overrides __get method from Laravel Model class that we will use in our code, When you call $category->title the “title” will be passed to __get as a $key parameter, and we will check if it is in the $multi_lang array?!If yes, we will append $key with the user language, So if the language is Arabic $key will be tilte_ar and if it English the $key will be title_en, Then we will call the parent __get method with the edited value, so it will act as call $category->title_ar or $category->title_en depending on the language.

<?php/** * Created by PhpStorm.

* User: abed * Date: 2/11/19 * Time: 4:04 PM */namespace AppTraits;use IlluminateSupportFacadesApp;trait MultiLanguage{/** * @param string $key * @return mixed */ public function __get($key) { if (isset($this->multi_lang) && in_array($key, $this->multi_lang)) { $key = $key .

'_' .

App::getLocale(); } return parent::__get($key); }}Now, Let’s create a UnitTest class to test our code.

php artisan make:test MultiLanguageTest –unitIn this test, we create an instance of Category and fill set the title_ar => “منشور” and title_en=>”Post”, Then we call the $mutli_lang property $category->title, Once when the language was Arabic, and once when it is English.

<?phpnamespace TestsUnit;use AppCategory;use IlluminateSupportFacadesApp;use TestsTestCase;class MultiLanguageTest extends TestCase{ /** * Test MutliLanguage Trait.

* * @return void */ public function testMultiLanguageAttribute() { $category = new Category; $category->fill(['title_ar' => 'منشور', 'title_en' => 'Post']); App::setLocale('ar'); $this->assertEquals($category->title, 'منشور');App::setLocale('en'); $this->assertEquals($category->title, 'Post'); }}Now in your terminal, inside your project directory run the PHPUnit test.

/vendor/phpunit/phpunit/phpunitMake sure you get OK as a result for your UnitTest, otherwise check that you’ve done everything correctly.

Finally, I hope you enjoyed and benefited from this article.

Special thanks to Osama for his great notes and additions.


. More details

Leave a Reply