stevebauman/translation

为 Laravel 5 设计的简单自动数据库驱动翻译器

此包的规范仓库似乎已消失,因此该包已被冻结。

v1.4.1 2016-06-27 20:46 UTC

README

Travis CI Scrutinizer Code Quality Latest Stable Version Total Downloads License

描述

Translation 是一个对开发者友好的、基于数据库的、为 Laravel 5 设计的自动翻译器。难道不希望只是正常地在您的应用程序中写文本,然后自动将其翻译、添加到数据库并在运行时缓存吗?例如:

控制器

public function index()
{
    return view('home.index');
}

视图

@extends('layout.default')

{{ _t('Welcome to our home page') }}

查看

Welcome to our home page

当您访问页面时,您不会注意到任何不同,但如果您查看您的数据库,您默认的应用程序区域设置已经创建,并且与该区域设置关联的翻译。

现在,如果我们设置区域设置为不同的值,例如法语(fr),它将自动为您翻译。

控制器

public function index()
{
    Translation::setLocale('fr');
    
    return view('home.index');
}

视图

@extends('layout.default')

{{ _t('Welcome to our home page') }}

查看

Bienvenue sur notre page d'accueil

我们甚至可以使用占位符来表示动态内容

视图

{{ _t('Welcome :name, to our home page', ['name' => 'John']) }}

查看

Bienvenue John , à notre page d'accueil

请注意,我们没有真正更改视图中的文本,这意味着对于您(开发者)来说,在您的区域设置中一切都是完全可读的,这意味着不再需要管理大量的翻译文件,并试图解码可能位于该点状翻译路径中的文本

{{ trans('page.home.index.welcome') }}

安装

要求翻译包

composer require stevebauman/translation

将服务提供者添加到您的 config/app.php 配置文件

'Stevebauman\Translation\TranslationServiceProvider',

将外观添加到您的 config/app.php 配置文件中的别名

'Translation' => 'Stevebauman\Translation\Facades\Translation',

发布迁移

php artisan vendor:publish --provider="Stevebauman\Translation\TranslationServiceProvider"

运行迁移

php artisan migrate

您可以开始了!

用法

在您的应用程序的任何地方,您都可以使用简短函数(可以在配置文件中禁用)

_t('Translate me!')

或者

Translation::translate('Translate me!')

这通常在 blade 视图中最有用

{{ _t('Translate me!') }}

您还可以通过插入您的内容轻松地翻译模型

{{ _t($post->title) }}

或者使用占位符

{{ _t('Post :title', ['title' => $post->title]) }}

在您的 locales 数据库表中您将会有

| id | code |  name  | display_name | lang_code |
   1    en    English      NULL          NULL

在您的 translations 数据库表中您将会有

| id | locale_id | translation_id | translation |
  1        NULL         NULL        'Translate me!'

要为用户会话切换语言,您只需要调用

Translation::setLocale('fr') // Setting to French locale

当您调用 Translation::setLocale($code) 方法时,会自动创建区域设置,当调用翻译函数时,它将自动为新的区域设置创建一个新的翻译记录,带有默认区域设置的翻译。默认区域设置取自 laravel 的 app.php 配置文件。

现在,一旦您访问页面,您将在您的 locales 表中看到以下内容

| id | code | name | display_name | lang_code |
   1    en    English     NULL         NULL
   2    fr    French      NULL         NULL

并且这将在您的 translations 表中

| id | locale_id | translation_id | translation |
   1        1         NULL        'Translate me!'
   2        2          1          'Traduisez-moi !'

现在您可以更新新记录中的翻译,并且它将在任何调用它的地方显示

_t('Translate me!')`
需要翻译单个文本而不设置用户默认区域设置吗?

只需将区域设置传递到上述翻译函数的第三个参数中,如下所示

视图

{{ _t('Our website also supports russian!', [], 'ru') }}

<br>

{{ _t('And french!', [], 'fr') }}

查看

Наш сайт также поддерживает России !

Et françaises !

这对于显示您的网站支持不同的语言而无需更改整个站点的语言本身非常有用。您也可以像往常一样执行替换

视图

{{ _t('Hello :name, we also support french!', ['name' => 'John Doe'], 'fr') }}

查看

Bonjour John Doe , nous soutenons aussi le français !

执行此操作还会在您的数据库中创建区域设置,保存翻译,并在需要时将其缓存。

您必须提供自己的方式来更新翻译(控制器/视图等),使用提供的 eloquent 模型。

注入翻译

v1.3.4 版本开始,您现在可以将 Translation 合同注入到您的控制器中,而不使用外观

use Stevebauman\Translation\Contracts\Translation;

class BlogController extends Controller
{
    /**
     * @var Translation
     */
    protected $translation;
    
    /**
     * Constructor.
     *
     * @param Translation $translation
     */
    public function __construct(Translation $translation)
    {
        $this->translation = $translation;
    }
    
    /**
     * Returns all blog entries.
     *
     * @return Illuminate\View\View
     */
    public function index()
    {
        $title = $this->translation->translate('My Blog');
        
        $entries = Blog::all();
        
        return view('pages.blog.index', compact('title', 'entries'));
    }
}

模型

默认情况下,配置文件中包含并选择了两个模型。如果您想使用自己的模型,您必须创建它们并实现它们的特性。以下是一个示例

地区模型

use Stevebauman\Translation\Traits\LocaleTrait;
use Illuminate\Database\Eloquent\Model;

class Locale extends Model
{
    use LocaleTrait;

    /**
     * The locales table.
     *
     * @var string
     */
    protected $table = 'locales';

    /**
     * The fillable locale attributes.
     *
     * @var array
     */
    protected $fillable = [
        'code',
        'lang_code',
        'name',
        'display_name',
    ];

    /**
     * {@inheritdoc]
     */
    public function translations()
    {
        return $this->hasMany(Translation::class);
    }
}

翻译模型

use Stevebauman\Translation\Traits\TranslationTrait;
use Illuminate\Database\Eloquent\Model;

class Translation extends Model
{
    use TranslationTrait;

    /**
     * The locale translations table.
     *
     * @var string
     */
    protected $table = 'translations';

    /**
     * The fillable locale translation attributes.
     *
     * @var array
     */
    protected $fillable = [
        'locale_id',
        'translation_id',
        'translation',
    ];

    /**
     * {@inheritdoc}
     */
    public function locale()
    {
        return $this->belongsTo(Locale::class);
    }

    /**
     * {@inheritdoc}
     */
    public function parent()
    {
        return $this->belongsTo(self::class);
    }
}

创建这些模型后,将它们插入到 translation.php 配置文件中

/*
|--------------------------------------------------------------------------
| Locale Model
|--------------------------------------------------------------------------
|
|  The locale model is used for storing locales such as `en` or `fr`.
|
*/

'locale' => App\Models\Locale::class,


/*
|--------------------------------------------------------------------------
| Translation Model
|--------------------------------------------------------------------------
|
|  The translation model is used for storing translations.
|
*/

'translation' => App\Models\Translation::class,

路由

使用地区前缀翻译您的网站非常简单。首先,在您的 app/Http/Kernel.php 文件中,插入地区中间件

/**
 * The application's route middleware.
 *
 * @var array
 */
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    
    // Insert Locale Middleware
    'locale' => \Stevebauman\Translation\Middleware\LocaleMiddleware::class
];

现在,在您的 app/Http/routes.php 文件中,在路由组前缀中插入中间件和以下翻译方法,如下所示

Route::group(['prefix' => Translation::getRoutePrefix(), 'middleware' => ['locale']], function()
{
    Route::get('home', function ()
    {
        return view('home');
    });
});

现在,您应该可以访问以下路由

https:///home
https:///en/home
https:///fr/home

自动翻译

自动翻译默认在配置文件中启用。它使用了 Stichoza 的 Google Translate PHP 包。使用自动翻译会将插入的文本发送到 Google,并将返回的文本保存到数据库中。一旦翻译保存到数据库中,它就不会再次发送到 Google 进行重新翻译。这意味着您不必担心 Google 可能设置的配额。您实际上拥有那些翻译。

问题 / 关注点

为什么在我的数据库翻译中,我的占位符应该出现的地方有下划线?

当您向翻译添加占位符并将数据添加到替换它时,例如

_t('Hi :name', ['name' => 'John'])

翻译会解析数据数组中的每个条目,以查看占位符是否确实存在于插入的数据中。例如,在您的数据库中的翻译字段中,以下内容被保存

_t('Hi :name', ['name' => 'John']) // Hi __name__

_t('Hi :name', ['test' => 'John']) // Hi :name

由于插入的占位符数据与字符串中的占位符不匹配,因此文本将保持不变。下划线的原因是因为 Google 翻译会尝试翻译包含 :name 的文本,然而在占位符两侧提供双下划线可以防止 Google 翻译那个特定的单词,使我们能够翻译其他所有内容,同时保持占位符完整。然后翻译在运行时替换占位符的双下划线变体(在这种情况下为 __name__)。

如果我更新 / 修改翻译函数中的文本,会发生什么?

如果您修改翻译函数中的文本,它将创建一条新记录,并且您需要再次进行翻译。这是有意为之,因为修改后可能完全是不同的翻译。

例如使用

{{ _t('Welcome!') }}

并将其修改为

{{ _t('Welcome') }}

将自动生成新的翻译记录。

自动翻译有文本数量上限吗?

更新:此包现在使用 Stichoza 的 3.0 更新。这允许您每次请求翻译多达 4200 个单词(已测试,可能更多)。

是的,根据 Google Translate PHP,有一个 1300 个单词的请求限制。只需确保将内容分成几部分,以免达到限制。

问题

我试图在路由文件中设置地区,但它从未改变?

您是否使用了 file 驱动程序进行会话?这是 Laravel 5 文件会话驱动程序的一个已知问题 laravel/framework#8244

暂时使用其他会话驱动程序,例如数组或数据库。