bureaupartners/laravel-gettext

使用 Poedit 和 GNU gettext 以简便方式为 Laravel 应用程序添加本地化支持。

7.3.0 2020-04-22 09:37 UTC

README

Laravel Gettext 是一个与优秀的 Laravel PHP 框架兼容的包。它提供了一种简单的方法来为 Laravel 应用程序添加本地化支持。它旨在与 GNU gettextPoedit 一起工作。此包的前版本(4.x 之前)与本机 php-gettext 模块兼容。当前版本默认使用 Symfony 翻译包,而不是本机 php 扩展。

稳定构建状态 最新的 Laravel 7 稳定版本(7.3.0)

注意:此文档适用于 laravel 5.5.x 及以上版本。对于旧版本的 Laravel,请查看以下链接

旧版本

稳定构建状态 最新的 Laravel 6 稳定版本(7.2.0)

稳定构建状态 最新的 Laravel 5.6.x & 5.7.x 稳定版本(7.1.0)

稳定构建状态 最新的 Laravel 5.5.x 稳定版本(6.1.0)

稳定构建状态 最新的 Laravel 5.4.x 稳定版本(5.0.2)

稳定构建状态 最新的 Laravel 5.3.x 稳定版本(4.0.4)

稳定构建状态 最新的 Laravel 5.2.x 稳定版本(3.1.0)

稳定构建状态 最新的Laravel 5.1.x稳定版本(3.0.3)

稳定构建状态 最新的Laravel 5.0稳定版本(2.0.3)

稳定构建状态 最新的Laravel 4.x稳定版本(1.0.3)

开发构建状态 开发master 不稳定,仅限开发(dev-master)

1. 要求

1.1 可选

1.1.1 APCU

APCU扩展已安装 - https://php.ac.cn/manual/en/book.apcu.php

如果已安装APCU php扩展,库将使用内存来缓存已加载的翻译,以避免在每个请求中解析翻译文件(mo/po)。

当翻译文件发生变化时,缓存将自动失效。

1.1.2 gettext

如果您想使用原生php-gettext扩展,这是可选的要求

为了使用原生php-gettext模块,您需要将'handler'选项更新为'gettext'。

2. 安装

将composer仓库添加到您的composer.json文件中

    "deepskylog/laravel-gettext": "7.x"

然后运行composer update。安装完成后,Laravel将自动发现提供者并加载它。(仅适用于5.5)

现在您需要发布配置文件以设置自己的应用程序值

    php artisan vendor:publish

此命令将在config/laravel-gettext.php中创建包配置文件。

您还需要在app/Http/Kernel.php文件中注册LaravelGettext中间件

    protected $middlewareGroups = [
        'web' => [
            // ...
            \deepskylog\LaravelGettext\Middleware\GettextMiddleware::class,
        ],
        // ...
    ]

确保在Illuminate\Session\Middleware\StartSession之后添加此行,否则区域设置将不会保存到会话中。

3. 配置

此时您的应用程序已经完全支持gettext。现在您需要在config/laravel-gettext.php中设置一些配置值。

    /**
     * Default locale: this will be the default for your application all
     * localized strings. Is to be supposed that all strings are written
     * on this language.
     */
    'locale' => 'es_ES',
    /**
     * Supported locales: An array containing all allowed languages
     */
    'supported-locales' => array(
        'es_ES',
        'en_US',
        'it_IT',
        'es_AR',
    ),
    /**
     * Default charset encoding.
     */
    'encoding' => 'UTF-8',

好的,现在已配置。是时候生成目录结构和翻译文件了。

在运行此命令之前,请确保您有对resources/的写入权限

    php artisan gettext:create

使用此命令将在resources/lang/i18n中创建所需的目录和文件

4. 工作流程

A. 编写字符串:D

默认情况下,LaravelGettext 会递归地搜索 app/Http/Controllers 和 resources/views 目录中的翻译。所有使用 _i() 函数打印的文本都被视为翻译。让我们看看一个简单的视图示例。

    // an example view file
    echo 'Non translated string';
    echo _i('Translated string');
    echo _i('Another translated string');
    // with parameter
    $str = 'parameter';
    $n = 2;
    echo _i('Translated string with %s', $str);
    echo _i('%dnd translated string with %s', [$n, $str]);
    // an example view in blade
    {{ _i('Translated string') }}

Poedit 不理解 blade 语法。当使用 blade 视图时,你必须运行 php artisan gettext:update 来编译所有 blade 视图成纯 PHP,然后再用 Poedit 更新翻译。

B. 复数字符串

复数翻译遵循相同的模式。所有使用 _n() 函数打印的文本都被视为复数翻译,并遵循 php ngettext。让我们看看一个简单的视图示例。

    // an example view file
    $n = 2;
    echo ($n > 1) ? 'Non translated plural string' : 'Non translated string';
    echo _n('Translated string', 'Translated plural string', $n);
    // with parameter
    $str = 'parameter';
    echo _n('Translated string %s', 'Translated plural string %s', 2, $str);
    // an example view in blade
    {{ _n('Translated string', 'Translated plural string', $n) }}

Poedit 的关键词在配置文件中用以下默认模式定义。

    ['_n:1,2', 'ngettext:1,2']

请参考 Poedit 用于配置您语言的复数形式

使用 Symfony

如果你使用 Symfony 作为你的翻译后端,你可以通过 _s 方法访问它们的复数语法。在 Poedit 中,它被视为单行而不是复数。

    // an example view file
    $n = 2;
    echo ($n > 1) ? 'Non translated plural string' : 'Non translated string';
    echo _s('Translated string|Translated plural string', $n);
    // with parameter
    $str = 'parameter';
    echo _n('Translated string %s|Translated plural string %s', 2, $str);

使用 symfony 复杂语法

    echo _s('{0} There are no apples|{1} There is one apple|]1,Inf[ There are %count% apples', $n);
    // with parameter
    $str = 'red';
    echo _s('{0} There are no %s apples|{1} There is one %s apple|]1,Inf[ There are %count% %s apples', 2, $str);
C. 使用 Poedit 翻译

用 Poedit 打开你想要翻译的语言的 PO 文件。PO 文件默认位于 resources/lang/i18n/[locale]/LC_MESSAGES/[domain].po。如果你有多个 gettext 域,每个域会生成一个文件。

加载 Poedit 后,按更新按钮加载所有本地化字符串。每次添加新的本地化字符串时,你可以重复此步骤。

在 Poedit 中填写翻译字段并保存文件。第一次这样做时,将为每个区域生成 MO 文件。

C. 运行时方法

要在运行时更改配置,你有以下方法

    /**
     * Sets the Current locale.
     * Example param value: 'es_ES'
     *
     * @param mixed $locale the locale
     * @return LaravelGettext
     */
    LaravelGettext::setLocale($locale);
    /**
     * Gets the Current locale.
     * Example returned value: 'es_ES'
     *
     * @return String
     */
     LaravelGettext::getLocale();
    /**
     * Gets the language portion of the locale.
     * Eg from en_GB, returns en
     *
     * @return mixed
     */
    LaravelGettext::getLocaleLanguage()
    /**
     * Sets the Current encoding.
     * Example param value: 'UTF-8'
     *
     * @param mixed $encoding the encoding
     * @return LaravelGettext
     */
     LaravelGettext::setEncoding($encoding);
    /**
     * Gets the Current encoding.
     * Example returned value: 'UTF-8'
     *
     * @return String
     */
     LaravelGettext::getEncoding();
    /**
     * Sets the current domain
     *
     * @param String $domain
     */
    LaravelGettext::setDomain($domain);
    /**
     * Returns the current domain
     *
     * @return String
     */
    LaravelGettext::getDomain();
    /**
     * Returns the language selector object
     *
     * @param  Array $labels
     * @return LanguageSelector
     */
    LaravelGettext::getSelector($labels = []);

5. 特性和示例

A. 路由和控制器实现示例

app/Http/routes.php

    Route::get('/lang/{locale?}', [
        'as'=>'lang',
        'uses'=>'HomeController@changeLang'
    ]);

app/Http/Controllers/HomeController.php

    /**
     * Changes the current language and returns to previous page
     * @return Redirect
     */
    public function changeLang($locale=null)
    {
        LaravelGettext::setLocale($locale);
        return Redirect::to(URL::previous());
    }

B. 基本语言选择器示例

  <ul>
      @foreach(Config::get('laravel-gettext.supported-locales') as $locale)
            <li><a href="/lang/{{$locale}}">{{$locale}}</a></li>
      @endforeach
  </ul>

C. 内置语言选择器

你可以在你的视图中使用内置的语言选择器

    // Plain php:
    LaravelGettext::getSelector()->render();

    // Blade views:
    {!! LaravelGettext::getSelector()->render() !!}

它还支持自定义标签

    LaravelGettext::getSelector([
        'en_US' => 'English',
        'es_ES' => 'Spanish',
        'de_DE' => 'Deutsch',
    ])->render();

D. 添加源目录和域

你可以通过编辑 source-paths 配置数组来实现这一点。默认情况下,已设置 resources/views 和 app/Http/Controllers。

    /**
     * Paths where Poedit will search recursively for strings to translate.
     * All paths are relative to app/ (don't use trailing slash).
     *
     * Remember to call artisan gettext:update after change this.
     */
    'source-paths' => array(
        'Http/Controllers',
        '../resources/views',
        'foo/bar',              // app/foo/bar
    ),

你可能希望你的 翻译在不同的文件中。在 GNUGettext 中,翻译通过域分开,域只是上下文名称。

Laravel-Gettext 总是为不属于任何域的所有路径设置一个默认域,其名称由 'domain' 配置选项确定。

要添加新域,只需将你的路径包裹在所需的域名中,如下例所示

    'source-paths' => array(
        'frontend' => array(
            'Http/Controllers',
            '../resources/views/frontend',
        ),
        'backend' => array(
            '../resources/views/backend',
        ),
        '../resources/views/misc',
    ),

此配置会为每种语言生成三个翻译文件: messages.pofrontend.pobackend.po

要更改当前域(路由中间件会是一个很好的地方来做这个操作)

    LaravelGettext::setDomain("backend");

记住: 每次更改 'source-paths' 选项时都要更新你的 gettext 文件,否则就无需这样做。

    php artisan gettext:update

此命令将更新你的 PO 文件,并保留当前的翻译。之后,你可以打开 Poedit 并点击更新按钮,以添加新路径中的新文本字符串。

你可以用相同的命令仅更新单个域的文件

    php artisan gettext:update --domain backend

E. 关于 gettext 缓存(仅适用于 php-gettext 原生模块)

有时当你编辑/添加 PO 文件中的翻译时,更改不会立即显示。这是因为 gettext 缓存系统保留了内容。最快速的修复方法是重启你的 web 服务器。

6. 贡献

如果你想帮助开发这个包,你可以

  • 在问题部分警告你发现的错误
  • 给我发送带有你的补丁的 pull request
  • 修复文档/注释中的糟糕英语;-)
  • 创建一个分支并创建laravel-gettext的自己的版本
  • 点个赞!

7. 从4.*版本升级

如果你是从4.版本升级,即Laravel 5.3的版本。,你需要重构对__方法的使用。

Laravel现在使用这个方法进行自己的翻译。你现在需要使用_i代替,并在Laravel-Gettext的配置文件中添加这个关键字

此外,如果你使用Symfony作为你的后端,你可以添加_s方法。它是为了使用Symfony复数语法的完整功能集。

  /**
     * The keywords list used by poedit to search the strings to be translated
     *
     * The "_", "__" and "gettext" are singular translation functions
     * The "_n" and "ngettext" are plural translation functions
     * The "dgettext" function allows a translation domain to be explicitly specified
     *
     * "__" and "_n" and "_i" and "_s" are helpers functions @see \deepskylog\LaravelGettext\Support\helpers.php
     */
    'keywords-list' => ['_', '__', '_i', '_s', 'gettext', '_n:1,2', 'ngettext:1,2', 'dgettext:2'],;