devuniverse / laravel-gettext
通过Poedit和GNU gettext轻松为Laravel应用添加本地化支持。
Requires
- php: >=8.2
- laravel/framework: ^11.0
- laravel/helpers: ^1.1
Requires (Dev)
- laravel/laravel: ^11.0
- mockery/mockery: dev-master
- php-coveralls/php-coveralls: ^2.1
- phpunit/phpunit: ^11.0
- squizlabs/php_codesniffer: 1.5.*
This package is auto-updated.
Last update: 2024-09-12 11:55:27 UTC
README
Laravel Gettext 是一个与优秀的 Laravel PHP 框架兼容的软件包。它提供了一个简单的方法将本地化支持添加到 Laravel 应用程序中。它旨在与 GNU gettext 和 Poedit 一起工作。此软件包的早期版本(4.x 之前)与原生的 php-gettext 模块一起工作。当前版本默认使用 Symfony 翻译包,而不是原生 php 扩展。
注意:本文档适用于 laravel 5.5.x 及以上版本。对于旧版本的 Laravel,请参阅以下链接
旧版本
最新的 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)
开发master 不稳定,仅用于开发(dev-master)
1. 要求
- Composer - http://www.getcomposer.org
- Laravel 5.5.* - http://www.laravel.com
- Poedit - https://poedit.net/
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 - https://php.ac.cn/manual/en/book.gettext.php
- 系统中的GNU gettext(包括生产服务器!) - https://gnu.ac.cn/software/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.po、frontend.po 和 backend.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'],;