devuniverse/gettext

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

7.8 2023-03-20 19:25 UTC

This package is auto-updated.

Last update: 2024-09-29 05:36:17 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)

开发构建状态 开发主分支 不稳定,仅用于开发(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文件中

    "zerospam/laravel-gettext": "6.x"

然后运行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视图时,你必须运行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. 贡献

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

  • 在问题部分报告您发现的错误
  • 通过您的补丁发送给我一个拉取请求
  • 修复文档/注释中的灾难性英语 ;-)
  • 创建一个分叉并创建您自己的 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'],;