beyaty / laravel-translatable

Laravel多语言模型包

v5.1 2015-05-07 16:07 UTC

README

Total Downloads Build Status Code Coverage Latest Stable Version License SensioLabsInsight

这是一个用于可翻译模型的Laravel包。其目标是简化获取和存储多语言模型实例的复杂性。使用此包,您编写的代码更少,因为翻译将在获取/保存实例时进行获取/保存。

如果您想将模型的翻译存储到数据库中,此包适合您。

Laravel兼容性

演示

获取翻译属性

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

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

保存翻译属性

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

填充多个翻译

  $data = [
    'code' => 'gr',
    'en'  => ['name' => 'Greece'],
    'fr'  => ['name' => 'Grèce'],
  ];

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

4步安装

步骤1:安装包

通过执行命令将包添加到您的composer.json中。

composer require dimsav/laravel-translatable

接下来,将服务提供者添加到app/config/app.php

'Dimsav\Translatable\TranslatableServiceProvider',

步骤2:迁移

在这个例子中,我们想翻译Country模型。我们需要一个额外的表country_translations

Schema::create('countries', function(Blueprint $table)
{
    $table->increments('id');
    $table->string('code');
    $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');
});

步骤3:模型

  1. 可翻译模型Country应使用Dimsav\Translatable\Translatable特性。
  2. 翻译模型的约定为CountryTranslation
// models/Country.php
class Country extends Eloquent {
    
    use \Dimsav\Translatable\Translatable;
    
    public $translatedAttributes = ['name'];
    protected $fillable = ['code', 'name'];

}

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

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

}

数组$translatedAttributes包含在“Translation”模型中翻译的字段名称。

步骤4:配置

Laravel 4.*

php artisan config:publish dimsav/laravel-translatable

Laravel 5.*

php artisan vendor:publish 

使用此命令初始化配置并修改创建的文件,位于app/config/packages/dimsav/laravel-translatable/translatable.php下。

注意:没有对区域设置的格式的限制。请随意使用您认为更好的格式,例如使用“eng”而不是“en”,或使用“el”而不是“gr”。重要的是要定义您的区域设置并坚持使用。

配置

翻译模型

用于定义翻译模型类的约定是在关键字后附加Translation

因此,如果您的模型是\MyApp\Models\Country,则默认翻译为\MyApp\Models\CountryTranslation

要使用自定义类作为翻译模型,将翻译类(包括命名空间)作为参数定义。例如

<?php 

namespace MyApp\Models;

use Dimsav\Translatable\Translatable;
use Illuminate\Database\Eloquent\Model as Eloquent;

class Country extends Eloquent
{
    use Translatable;

    public $translationModel = 'MyApp\Models\CountryAwesomeTranslation';
}

文档

请首先阅读安装步骤,了解需要创建哪些类。

可用方法

// This is how we determine the current locale.
// It is set by laravel or other packages.
App::getLocale(); // 'fr' 

// To use this package, first we need an instance of our model
$germany = Country::where('code', 'de')->first();

// This returns an instance of CountryTranslation of using the current locale.
// So in this case, french. If no french translation is found, it returns null.
$translation = $germany->translate();

// If an german translation exists, it returns an instance of 
// CountryTranslation. Otherwise it returns null.
$translation = $germany->translate('de');

// If a german translation doesn't exist, it attempts to get a translation  
// of the fallback language (see fallback locale section below).
$translation = $germany->translate('de', true);

// Alias of the above.
$translation = $germany->translateOrDefault('de');

// Returns instance of CountryTranslation of using the current locale.
// If no translation is found, it returns a fallback translation
// if enabled in the configuration.
$translation = $germany->getTranslation();

// If an german translation exists, it returns an instance of 
// CountryTranslation. Otherwise it returns null.
// Same as $germany->translate('de');
$translation = $germany->getTranslation('de', true);

// Returns true/false if the model has translation about the current locale. 
$germany->hasTranslation();

// Returns true/false if the model has translation in french. 
$germany->hasTranslation('fr');

// If a german translation doesn't exist, it returns
// a new instance of CountryTranslation.
$translation = $germany->translateOrNew('de');

// Returns a new CountryTranslation instance for the selected
// language, and binds it to $germany
$translation = $germany->getNewTranslation('it');

// The eloquent model relationship. Do what you want with it ;) 
$germany->translations();

魔术属性

要使用魔术属性,您必须在主模型中定义属性$translatedAttributes

class Country extends Eloquent {

    use \Dimsav\Translatable\Translatable;

    public $translatedAttributes = ['name'];
}
// Again we start by having a country instance
$germany = Country::where('code', 'de')->first();

// We can reference properties of the translation object directly from our main model.
// This uses the default locale and is the equivalent of $germany->translate()->name
$germany->name; // 'Germany'

// We can also quick access a translation with a custom locale
$germany->{'name:de'} // 'Deutschland'

回退区域设置

如果您希望在找不到翻译时回退到默认翻译,请使用use_fallback键在配置中启用它。要选择默认区域设置,请使用fallback_locale键。

示例

return [
    'use_fallback' => true,

    'fallback_locale' => 'en',    
];

您还可以通过将$useTranslationFallback属性设置为“true”来为每个模型定义“是否使用回退”的默认值。

class Country {

    public $useTranslationFallback = true;

}

常见问题解答

我需要一些示例代码!

有关此包所有功能的示例可以在代码中找到,这些代码用于测试

我需要帮助!

有任何问题或建议?请随意创建一个问题

我想帮忙!

你太棒了!观看了代码仓库并回复了问题。你将为软件包的用户提供极好的体验。 #社区工作

我在其他特质方法中遇到了冲突!

Translatable与所有类型的Eloquent扩展完全兼容,包括Ardent。如果你需要帮助实现与这些扩展的Translatable,请参阅此示例

为什么在运行迁移时我会得到一个mysql错误?

如果你看到以下mysql错误

[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)

那么你的表使用的是MyISAM引擎,该引擎不允许外键约束。MyISAM是5.5版本之前mysql的默认引擎。从5.5版本开始,默认使用InnoDB存储引擎创建表。

如何修复

对于已创建在生产环境中的表,更新迁移以在添加外键约束之前更改表的引擎。

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

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

对于新表,一个快速解决方案是在迁移中设置存储引擎

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

然而,最好的解决方案是更新你的mysql版本。并且务必确保开发和生产环境中使用相同的版本!