stevebauman/translation 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

stevebauman/translation

最新稳定版本:v1.4.1

Composer 安装命令:

composer require stevebauman/translation

包简介

An easy automatic database driven translator for Laravel 5

README 文档

README

Travis CI Scrutinizer Code Quality Latest Stable Version Total Downloads License

Description

Translation is a developer friendly, database driven, automatic translator for Laravel 5. Wouldn't it be nice to just write text regularly on your application and have it automatically translated, added to the database, and cached at runtime? Take this for example:

Controller:

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

View:

@extends('layout.default')

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

Seen:

Welcome to our home page

When you visit the page, you won't notice anything different, but if you take a look at your database, your default application locale has already been created, and the translation attached to that locale.

Now if we set locale to something different, such as French (fr), it'll automatically translate it for you.

Controller:

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

View:

@extends('layout.default')

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

Seen:

Bienvenue sur notre page d'accueil

We can even use placeholders for dynamic content:

View:

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

Seen:

Bienvenue John , à notre page d'accueil

Notice that we didn't actually change the text inside the view, which means everything stays completely readable in your locale to you (the developer!), which means no more managing tons of translation files and trying to decipher what text may be inside that dot-notated translation path:

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

Installation

Require the translation package

composer require stevebauman/translation

Add the service provider to your config/app.php config file

'Stevebauman\Translation\TranslationServiceProvider',

Add the facade to your aliases in your config/app.php config file

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

Publish the migrations

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

Run the migrations

php artisan migrate

Your good to go!

Usage

Anywhere in your application, either use the the shorthand function (can be disabled in config file)

_t('Translate me!')

Or

Translation::translate('Translate me!')

This is typically most useful in blade views:

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

And you can even translate models easily by just plugging in your content:

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

Or use placeholders:

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

In your locales database table you'll have:

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

In your translations database table you'll have:

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

To switch languages for the users session, all you need to call is:

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

Locales are automatically created when you call the Translation::setLocale($code) method, and when the translate function is called, it will automatically create a new translation record for the new locale, with the default locale translation. The default locale is taken from the laravel app.php config file.

Now, once you visit the page you'll have this in your locales table:

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

And this in your translations table:

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

You can now update the translation on the new record and it will be shown wherever it's called:

_t('Translate me!')`
Need to translate a single piece of text without setting the users default locale?

Just pass in the locale into the third argument inside the translation functions show above like so:

View:

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

<br>

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

Seen:

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

Et françaises !

This is great for showing users that your site supports different languages without changing the entire site language itself. You can also perform replacements like usual:

View:

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

Seen:

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

Performing this will also create the locale in your database, save the translation, and cache it in case you need it again.

You must provide you're own way of updating translations (controllers/views etc) using the eloquent models provided.

Injecting Translation

As of v1.3.4 you can now inject the Translation contract into your controllers without the use of a facade:

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'));
    }
}

Models

By default, two models are included and selected inside the configuration file. If you'd like to use your own models you must create them and implement their trait. Here's an example:

The Locale Model:

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);
    }
}

The Translation Model:

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);
    }
}

Once you've created these models, insert them into the translation.php configuration file:

/*
|--------------------------------------------------------------------------
| 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,

Routes

Translating your site with a locale prefix couldn't be easier. First inside your app/Http/Kernel.php file, insert the locale middleware:

/**
 * 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
];

Now, in your app/Http/routes.php file, insert the middleware and the following Translation method in the route group prefix like so:

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

You should now be able to access routes such as:

http://localhost/home
http://localhost/en/home
http://localhost/fr/home

Automatic Translation

Automatic translation is enabled by default in the configuration file. It utilizes the fantastic package Google Translate PHP by Stichoza. Using automatic translation will send the inserted text to google and save the returned text to the database. Once a translation is saved in the database, it is never sent back to google to get re-translated. This means that you don't have to worry about hitting a cap that google may impose. You effectively own that translation.

Questions / Concerns

Why are there underscores where my placeholders should be in my database translations?

When you add placeholders to your translation, and add the data to replace it, for example:

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

Translation parses each entry in the data array to see if the placeholder actually exists for the data inserted. For example, in the translation field in your database, here is what is saved:

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

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

Since the placeholder data inserted doesn't match a placeholder inside the string, the text will be left as is. The reason for the underscores is because google translate will try to translate text containing :name, however providing double underscores on both sides of the placeholder, prevents google from translating that specific word, allowing us to translate everything else, but keep placeholders in tact. Translation then replaces the double underscore variant of the placeholder (in this case __name__) at runtime.

If I update / modify the text inside the translation function, what happens to it's translations?

If you modify the text inside a translation function, it will create a new record and you will need to translate it again. This is intended because it could be a completely different translation after modification.

For example using:

{{ _t('Welcome!') }}

And modifying it to:

{{ _t('Welcome') }}

Would automatically generate a new translation record.

Is there a maximum amount of text that can be auto-translated?

Update: This package now uses Stichoza's new 3.0 update. This allows you to translate up to 4200 words per request (tested, possibly more allowed).

Yes, according to Google Translate PHP there is a 1300 word limit per request. Just be sure to break you're content up so you don't hit the limit.

Issues

I'm trying to set the locale in my routes file but it never changes?

Are you using the file driver for sessions by chance? This is a known issue with the Laravel 5 file session driver laravel/framework#8244.

Use another session driver for the time being, such as array or database.

stevebauman/translation 适用场景与选型建议

stevebauman/translation 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 20.12k 次下载、GitHub Stars 达 75, 最近一次更新时间为 2015 年 02 月 04 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 stevebauman/translation 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 stevebauman/translation 我们能提供哪些服务?
定制开发 / 二次开发

基于 stevebauman/translation 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 20.12k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 76
  • 点击次数: 25
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 75
  • Watchers: 8
  • Forks: 32
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2015-02-04