Skip to content

jonasva/laravel-translatable

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Laravel-Translatable

Latest Stable Version Build Status Code Coverage License SensioLabsInsight

This is a Laravel 4 package for translatable models. Its goal is to remove the complexity in retrieving and storing multilingual model instances. With this package you write less code, as the translations are being fetched/saved when you fetch/save your instance.

If you want to store translations of your models into the database, this package is for you.

Demo

Getting translated attributes

  $country = Country::where('iso', '=', 'gr')->first();
  echo $country->translate('en')->name; // Greece
  
  App::setLocale('en');
  echo $country->name;     // Greece

  App::setLocale('de');
  echo $country->name;     // Griechenland

Saving translated attributes

  $country = Country::where('iso', '=', 'gr')->first();
  echo $country->translate('en')->name; // Greece
  
  $country->translate('en')->name = 'abc';
  $country->save();
  
  $country = Country::where('iso', '=', 'gr')->first();
  echo $country->translate('en')->name; // abc

Filling multiple translations

  $data = array(
    'iso' => 'gr',
    'en'  => array('name' => 'Greece'),
    'fr'  => array('name' => 'Grèce'),
  );

  $country = Country::create($data);
  
  echo $country->translate('fr')->name; // Grèce

Installation in 4 steps

Step 1

Add the package in your composer.json file and run composer update.

{
    "require": {
        "dimsav/laravel-translatable": "4.3.*"
    }
}

Step 2

Let's say you have a model Country. To save the translations of countries you need one extra table country_translations.

Create your migrations:

Schema::create('countries', function(Blueprint $table)
{
    $table->increments('id');
    $table->string('iso');
    $table->timestamps();
});

Schema::create('country_translations', function(Blueprint $table)
{
    $table->increments('id');
    $table->integer('country_id')->unsigned();
    $table->string('name');
    $table->string('locale')->index();

    $table->unique(['country_id','locale']);
    $table->foreign('country_id')->references('id')->on('countries')->onDelete('cascade');
});

Step 3

The models:

  1. The translatable model Country should use the trait Dimsav\Translatable\Translatable.
  2. The convention for the translation model is CountryTranslation.
// models/Country.php
class Country extends Eloquent {
    
    use \Dimsav\Translatable\Translatable;
    
    public $translatedAttributes = array('name');
    protected $fillable = ['iso', 'name'];

}

// models/CountryTranslation.php
class CountryTranslation extends Eloquent {

    public $timestamps = false;
    protected $fillable = ['name'];

}

The array $translatedAttributes contains the names of the fields being translated in the "Translation" model.

Step 4

Optionally, edit the default locale.

// app/config/app.php

return array(

  // Just enter this array somewhere near your default locale
  'locales' => array('en', 'fr', 'es'),

  // The default locale
  'locale' => 'en',

  // Override the default 'Translation' class suffix
  // to use CountryTrans instead of CountryTranslation
  'translatable_suffix' => 'Trans'

);

Note: There isn't any restriction for the format of the locales. Feel free to use whatever suits you better, like "eng" instead of "en", or "el" instead of "gr". The important is to define your locales and stick to them till the end.

Laravel versions

Laravel versions 4.0, 4.1 and 4.2 play nice with the package.

FAQ

I need help!

Got any question or suggestion? Feel free to open an Issue.

I want to help!

You are awesome! Watched the repo and reply to the issues. You will help offering a great experience to the users of the package. #communityWorks

Is this compatible with Ardent?

Translatable is fully compatible with all kinds of Eloquent extensions, including Ardent. If you need help to implement Translatable with these extensions, see this example.

Why do I get a mysql error while running the migrations?

If you see the following mysql error:

[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1005 Can't create table 'my_database.#sql-455_63'
  (errno: 150) (SQL: alter table `country_translations` 
  add constraint country_translations_country_id_foreign foreign key (`country_id`) 
  references `countries` (`id`) on delete cascade)

Then your tables have the MyISAM engine which doesn't allow foreign key constraints. MyISAM was the default engine for mysql versions older than 5.5. Since version 5.5, tables are created using the InnoDB storage engine by default.

How to fix

For tables already created in production, update your migrations to change the engine of the table before adding the foreign key constraint.

public function up()
{
	DB::statement('ALTER TABLE countries ENGINE=InnoDB');
}

public function down()
{
  DB::statement('ALTER TABLE countries ENGINE=MyISAM');
}

For new tables, a quick solution is to set the storage engine in the migration:

Schema::create('language_translations', function(Blueprint $table){
  $table->engine = 'InnoDB';
  $table->increments('id');
	// ...
});

The best solution though would be to update your mysql version. And always make sure you have the same version both in development and production environment!

Version History

v. 4.3

  • The Translation class suffix default can be overridden in the app config. See 7ecc0a75d
  • The app.fallback_locale setting can be overridden in each model separately. See #33
  • Fallback translation is not returned if it is not defined.

v. 4.2

  • Fallback locale now is taken from app.fallback_locale config key.

v. 4.1.1

  • Fixed issue with saving translations, caused by the update of the laravel core.

v. 4.1

  • Added fallback to default locale if translations is missing.
  • Added travis environment for laravel 4.2.

v. 4.0

  • Removed syntax $model->en->name because conflicts may happen if the model has a property named en. See #18.
  • Added method hasTranslation($locale). See #19.

v. 3.0

  • Fixed bug #7. Model's Translations were deleted when the model delete failed.

v. 2.0

  • Translatable is now a trait and can be used as add-on to your models.
  • 100% code coverage

v. 1.0

  • Initial version
  • Translatable is a class extending Eloquent
  • 96% code coverage

About

A Laravel package for multilingual models

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 100.0%