欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

laravel-translatable, 用于多语言模型的Laravel 包 数据库多语言 有大用

  • 显示原文与译文双语对照的内容

文章标签:模式  PAC  Laravel  PACK  
           
A Laravel package for multilingual models

  • 源代码名称:laravel-translatable

  • 源代码网址:http://www.github.com/dimsav/laravel-translatable

  • laravel-translatable源代码文档

  • laravel-translatable源代码下载


  • Git URL:

    git://www.github.com/dimsav/laravel-translatable.git

                                   

                               

  • Git Clone代码到本地:

    git clone http://www.github.com/dimsav/laravel-translatable

                                   

                               

  • Subversion代码到本地:

    $ svn co --depth empty http://www.github.com/dimsav/laravel-translatable
    Checked out revision 1.
    $ cd repo
    $ svn up trunk

                                   

                               

laravel可以翻译

Total DownloadsBuild StatusCode CoverageLatest Stable VersionLicenseSensioLabsInsightStyleCI                        

Laravel Translatable                        

如果你想将模型的翻译存储到数据库中,这个包是为你准备的。

这是一个 Laravel 包,用于。 它的目标是消除检索和存储多语言模型实例的复杂性。 当你获取/保存你的实例时,你将编写更少的代码,因为在获取/保存的。

文档

演示

获取翻译属性

$greece=Country::where('code', 'gr')->first();echo$greece->translate('en')->name; // GreeceApp::setLocale('en');echo$greece->name; // GreeceApp::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
                       

Laravel 兼容性

Laravel 可以翻译


5.58.0
5.47.*
5.36.*
5.25.5 - 6 *
5.15.0 - 6 *
5.05.0 - 5.4
4.2.x4.4.x
4.1.x4.4.x
4.0.x4.3.x

教程

安装在 4个步骤中

步骤 1: 安装软件包

通过执行命令在 composer.json 中添加包。

composer require dimsav/laravel-translatable
                       

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

DimsavTranslatableTranslatableServiceProvider::class,
                       

步骤 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 应该使用特性 。

  • 翻译模型的约定是 CountryTranslation 。

// models/Country.phpclassCountryextendsEloquent {useDimsavTranslatableTranslatable;public$translatedAttributes= ['name'];protected$fillable= ['code'];/** * The relations to eager load on every query. * * @var array*/// (optionaly)// protected $with = ['translations'];}// models/CountryTranslation.phpclassCountryTranslationextendsEloquent {public$timestamps=false;protected$fillable= ['name'];}
                       

array $translatedAttributes 包含在"翻译"模型中被翻译的字段的名称。

步骤 4: 配置

我们将配置文件复制到我们的项目中。

Laravel 5.*

php artisan vendor:publish --tag=translatable 
                       

Laravel 4.*

php artisan config:publish dimsav/laravel-translatable
                       

注意:对区域设置的格式没有任何限制。 可以随意使用任何适合你的东西,比如"工程工程",而不是"en",或者"el",而不是"gr"。 重要的是定义你的地区并坚持它们。

配置

配置文件

你可以在配置文件中看到进一步定制的选项。

翻译模型

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

所以如果你的模型是 MyAppModelsCountry,默认的翻译是 MyAppModelsCountryTranslation

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

<?phpnamespaceMyAppModels;useDimsavTranslatableTranslatable;useIlluminateDatabaseEloquentModelasEloquent;classCountryextendsEloquent{useTranslatable;public$translationModel='MyAppModelsCountryAwesomeTranslation';}
                       

功能列表

请先阅读安装步骤,了解需要创建什么类。

可用方法

// Before we get started, this is how we determine the default 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 default locale.// So in this case, french. If no french translation is found, it returns null.$translation=$germany->translate();// It is possible to define a default locale per model by overriding the model constructor.publicfunction__construct(array$attributes= []){parent::__construct($attributes);$this->defaultLocale='de';}// It is also possible to define a default locale for our model on the fly:$germany->setDefaultLocale('de');// 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 default 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);// To set the translation for a field you can either update the translation model.// Saving the model will also save all the related translations.$germany->translate('en')->name='Germany';$germany->save();// Alternatively we can use the shortcut$germany->{'name:en'} ='Germany';$germany->save();// There are two ways of inserting mutliple translations into the database// First, using the locale as array key.$greece=$country->fill(['en'=> ['name'=>'Greece'],'fr'=> ['name'=>'Grèce'],]);// The second way is to use the following syntax. $greece=$country->fill(['name:en'=>'Greece','name:fr'=>'Grèce',]);// 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();// Remove all translations linked to an object$germany->deleteTranslations();// Delete one or multiple translations$germany->deleteTranslations('de');$germany->deleteTranslations(['de', 'en']);// Gel all the translations as array$germany->getTranslationsArray();// Returns['en'=> ['name'=>'Germany'],'de'=> ['name'=>'Deutschland'],'fr'=> ['name'=>'Allemagne'],];// Creates a clone and clones the translations$replicate=$germany->replicateWithTranslations(); 
                       

可用范围

// Returns all countries having translations in englishCountry::translatedIn('en')->get();// Returns all countries not being translated in englishCountry::notTranslatedIn('en')->get();// Returns all countries having translationsCountry::translated()->get();// Eager loads translation relationship only for the default// and fallback (if enabled) localeCountry::withTranslation()->get();// Returns an array containing pairs of country ids and the translated// name attribute. For example: // [// ['id' => 1, 'name' => 'Greece'], // ['id' => 2, 'name' => 'Belgium']// ]Country::listsTranslations('name')->get()->toArray();// Filters countries by checking the translation against the given value Country::whereTranslation('name', 'Greece')->first();// Or where translationCountry::whereTranslation('name', 'Greece')->orWhereTranslation('name', 'France')->get();// Filters countries by checking the translation against the given string with wildcardsCountry::whereTranslationLike('name', '%Gree%')->first();// Or where translation likeCountry::whereTranslationLike('name', '%eece%')->orWhereTranslationLike('name', '%ance%')->get();
                       

魔法特性

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

classCountryextendsEloquent {useDimsavTranslatableTranslatable;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 属性,定义每个模型( 默认为"是否应使用回退"的默认值):

classCountry {public$useTranslationFallback=true;}
每个属性的回退

尽管我们尝试 Having 所有模型都很好地翻译,有些字段可能。 结果如何你最终将丢失这些字段的翻译? !

属性回退功能在这里帮助。 启用后,可以翻译将返回那些空属性的回退语言的值。

新安装默认启用该功能。 如果在v7.1之前设置了配置文件,请确保添加了以下行以启用该功能:

'use_property_fallback'=>true,
                       

当然,必须启用备用区域设置才能使用这里功能。

如果在配置中启用了属性回退,那么可以翻译将返回转换为空的字段的回退区域设置。

基于的国家/地区后备                        

自v5.3版以来,可以使用基于国家地区的语言环境。 例如你可以拥有以下区域设置:

  • en:

  • 西班牙语:es

  • 墨西哥西班牙语:es-MX

  • 哥伦比亚西班牙语:es-CO

对于这些区域设置的配置如下所示:

'locales'=> [ 'en','es'=> ['MX','CO', ], ];
                       

我们还可以在语言和国家之间配置"粘附"。 例如我们更喜欢 es_MX 格式而不是 es-MX,配置应该如下所示:

'locale_separator'=>'_',
                       

使用 en-MX 格式对区域设置进行回退的内容?

假设我们的后备区域设置为 en 。 现在,当我们尝试从数据库中获取 es-MX的翻译时,它不存在,我们将不会回退 en 。 translate将用作回退 es ( 。es-MX的第一部分),只有在没有找到任何内容时,en的翻译才会返回。

添加

感谢社区,在使用表单时,已经编写了一些软件包来简化可以翻译的使用:

常见问题解答

我需要一些示例代码 !

可以在代码中找到所有软件包特性的示例,这些特性在用于测试的代码中使用。                        

我需要帮助 !

有任何问题或者建议? 请随意打开一个发行版。                        

我想帮助你 !

你真棒注意 repo 并回答问题。 你将帮助为软件包的用户提供很好的体验。 #communityWorks                        

也请给我买一个捐款。                        

:我与其他特征方法有冲突 !

Translatable是完全兼容所有种类的扩展,包括热情的扩展。 如果需要使用这些扩展实现翻译,请参见这个示例。                        

如何将现有表迁移到laravel可以翻译?

请参阅安装步骤以了解如何构造数据库。

如果你的属性是用英文编写的,我们建议你在迁移中使用这些命令:

// We insert the translation attributes into the fresh translated table: DB::statement("insert into country_translations (country_id, name, locale) select id, name, 'en' from countries");// We drop the translation attributes in our main table: Schema::table('countries', function ($table) {$table->dropColumn('name');}); 
:如何按翻译排序

这里的技巧是先让MySQL查询,然后做一些有说服力的事情。

要获取由翻译字段排序的记录列表,可以执行以下操作:

SELECT*from countriesJOIN country_translations as t ont.country_id=countries.idWHERE locale ='en'GROUP BYcountries.idORDER BYt.namedesc
                       

相应的eloquent查询将是:

Country::join('country_translations as t', function ($join) {$join->on('countries.id', '=', 't.country_id')->where('t.locale', '=', 'en'); }) ->groupBy('countries.id')->orderBy('t.name', 'desc')->with('translations')->get();
如何通过翻译字段选择国家/地区?

例如,让我们想象一下,我们想找到国家 Having的CountryTranslation NAME 等于'葡萄牙语'。

Country::whereHas('translations', function ($query) {$query->where('locale', 'en')->where('name', 'Portugal');})->first();
                       

你可以在 Laravel 查询关系文档找到更多信息。

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

如果你看到以下mysql错误:

[IlluminateDatabaseQueryException]
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是mysql版本早于 5.5的默认引擎。 由于版本 5.5,表是在默认情况下使用InnoDB存储引擎创建的。                        

如何修复

对于已经在生产中创建的表,更新迁移以更改表的引擎,然后再添加外部键约束。

publicfunctionup(){DB::statement('ALTER TABLE countries ENGINE=InnoDB');}publicfunctiondown(){DB::statement('ALTER TABLE countries ENGINE=MyISAM');}
                       

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

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

最好的解决方案是更新你的mysql版本。 总是你在开发和生产环境中拥有相同的版本 !

捐赠

这个软件被精心设计和喜爱。

通过将比特币发送到这里地址来展示你的爱和支持: 167QC4XQ3acgbwVYWAdmS81jARCcVTWBXU                        

或者发送到这里PayPal地址: ds@dimsav.com                        

来自  https://www.helplib.com/GitHub/article_107178                        


                       



普通分类: