devuniverse/laravel-gettext

通过Poedit和GNU gettext轻松为Laravel应用添加本地化支持。

v1.0.0 2024-03-19 04:04 UTC

This package is auto-updated.

Last update: 2024-09-12 11:55:27 UTC


README

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

Stable build Status 最新的 Laravel 6 稳定版本 (7.2.0)

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

旧版本

Stable build Status 最新的 Laravel 5.6.x & 5.7.x 稳定版本 (7.1.0)

Stable build Status 最新的 Laravel 5.5.x 稳定版本 (6.1.0)

Stable build Status 最新的 Laravel 5.4.x 稳定版本 (5.0.2)

Stable build Status 最新的 Laravel 5.3.x 稳定版本 (4.0.4)

Stable build Status 最新的 Laravel 5.2.x 稳定版本 (3.1.0)

Stable build Status 最新的 Laravel 5.1.x 稳定版本 (3.0.3)

Stable build Status 最新的 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文件中

    composer require devuniverse/laravel-gettext

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

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

    php artisan vendor:publish

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

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

    protected $middlewareGroups = [
        'web' => [
            // ...
            \Xinax\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视图时,必须在更新Poedit中的翻译之前运行php artisan gettext:update来编译所有blade视图为纯php

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. 贡献

如果您想帮助开发此包,您可以

  • 在问题部分报告您发现的错误
  • 通过您的补丁向我发送拉取请求
  • 修复文档/注释中的灾难性英语 ;-)
  • 创建分支并创建您自己的 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 \Xinax\LaravelGettext\Support\helpers.php
     */
    'keywords-list' => ['_', '__', '_i', '_s', 'gettext', '_n:1,2', 'ngettext:1,2', 'dgettext:2'],;