pokovc/laravel-gettext

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

1.0.0 2023-11-06 09:29 UTC

This package is auto-updated.

Last update: 2024-09-06 11:05:45 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 文件

    "pokovc/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' => [
            // ...
            \pokovc\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 \pokovc\LaravelGettext\Support\helpers.php
     */
    'keywords-list' => ['_', '__', '_i', '_s', 'gettext', '_n:1,2', 'ngettext:1,2', 'dgettext:2'],;