beyaty / laravel-translatable
Laravel多语言模型包
Requires
- php: >=5.4.0
- illuminate/support: ~5.0
Requires (Dev)
- orchestra/testbench: ~3.0
- phpunit/phpunit: ~4.0
README
这是一个用于可翻译模型的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:模型
- 可翻译模型
Country
应使用Dimsav\Translatable\Translatable
特性。 - 翻译模型的约定为
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版本。并且务必确保开发和生产环境中使用相同的版本!