admad / cakephp-i18n
CakePHP 的 I18n 工具插件。
Requires
- cakephp/cakephp: ^5.0
Requires (Dev)
- phpunit/phpunit: ^10.1
README
简介
此插件提供
- 用于生成和匹配带有语言前缀的 URL 的路由类。
- 中间件,使用
I18n::setLocale()
根据 URL 中的语言前缀设置区域设置,并在访问网站根目录时提供重定向到带有语言前缀的适当 URL。 - 用于检索存储在数据库中而不是 po/mo 文件中的翻译消息的类。
- 用于自动翻译验证消息的验证类。
- 用于生成具有时区标识符列表的复选框的小部件。
安装
composer require admad/cakephp-i18n
用法
运行命令来加载插件
bin/cake plugin load ADmad/I18n
该插件包含多个用于国际化的有用类。您可以选择您需要的类。
I18nRoute
I18nRoutes
帮助生成风格为 /{lang}/{controller}/{action}
的语言前缀路由。
例如,您可以在 routes.php
中添加类似于以下所示的路由
$routes->scope('/', function ($routes) { $routes->connect( '/{controller}', ['action' => 'index'], ['routeClass' => 'ADmad/I18n.I18nRoute'] ); $routes->connect( '/{controller}/{action}/*', [], ['routeClass' => 'ADmad/I18n.I18nRoute'] ); });
片段 /{lang}
将自动添加到路由中,允许匹配类似于 /en/posts
、/en/posts/add
等的 URL。元素 lang
会持久化,以便在生成 URL 时,如果 URL 数组中没有提供 lang
键,它将根据当前 URL 自动添加。
在连接路由时,您可以使用 lang
键在选项中提供仅匹配您的应用程序支持的语言的正则表达式。或者,您也可以设置配置值 I18n.languages
,该路由类将使用它来自动生成匹配 lang
元素的正则表达式。
Configure::write('I18n.languages', ['en', 'fr', 'de']);
注意:I18nRoute
扩展了核心的 DashedRoute
,因此 URL 片段将相应地变形。
I18nMiddleware
尽管不是必需的,但通常在使用 I18nRoute
帮助的语言前缀路由时,也会使用 I18nMiddleware
。
您可以在 src/Application::middleware()
中设置 I18nMiddleware
,如下所示
$middlware->add(new \ADmad\I18n\Middleware\I18nMiddleware([ // If `true` will attempt to get matching languges in "languages" list based // on browser locale and redirect to that when going to site root. 'detectLanguage' => true, // Default language for app. If language detection is disabled or no // matching language is found redirect to this language 'defaultLanguage' => 'en', // Languages available in app. The keys should match the language prefix used // in URLs. Based on the language the locale will be also set. 'languages' => [ 'en' => ['locale' => 'en_US'], 'fr' => ['locale' => 'fr_FR'] ], ]));
languages
数组的键是您在 URL 中使用的语言前缀。
为了确保 lang
路由参数可用,您必须在添加 CakePHP 的默认路由中间件(即添加 ->add(new RoutingMiddleware($this))
)之后添加此中间件。
中间件主要执行以下两项操作
-
当访问网站根目录
/
时,它将用户重定向到带有语言前缀的 URL,例如/en
。重定向到的语言取决于上述配置键detectLanguage
和defaultLanguage
。现在,为了防止 CakePHP 抱怨
/
的路由缺失,您必须将一个路由连接到/
,该控制器动作永远不会实际调用,因为中间件将拦截并重定向请求。例如,
$routes->connect('/', ['controller' => 'Foo']);
-
当访问任何带有语言前缀的 URL 时,它将根据前缀设置应用程序的区域设置。为此,它检查当前请求的参数中
lang
路由元素的值。如果使用了I18nRoute
连接了匹配的路由,则此路由元素将可用。使用为
languages
键提供的数组,通过Configure::write()
将App.language
配置设置为语言前缀,而locale
的值则用于I18n::setLocale()
调用。
DbMessagesLoader
默认情况下,CakePHP 使用 .po
文件来存储静态字符串翻译。如果你出于某种原因不想使用 .po
文件,可以使用 DbMessagesLoader
类将翻译消息存储在数据库中。我个人认为,将消息存储在表中而不是 .po
文件中,使得创建用于管理翻译的 Web 界面变得更容易。
要使用此类,首先使用插件 config
文件夹中提供的 SQL 文件创建数据库表。
在您的应用 config/bootstrap.php
文件中添加类似于以下代码:
// NOTE: This is should be done below Cache config setup. // Configure I18n to use DbMessagesLoader for default domain. You need to do // this for each domain separately. \Cake\I18n\I18n::config('default', function ($domain, $locale) { $loader = new \ADmad\I18n\I18n\DbMessagesLoader( $domain, $locale ); return $loader(); });
您可以使用 admad/i18n extract
命令从您的代码文件中提取翻译消息,并填充翻译表。更新每个语言的数据库记录的翻译则取决于您。
bin/cake admad/i18n extract
现在,您可以使用 __()
等翻译函数,就像您通常那样。I18n
类将从数据库而不是 .po
文件中获取所需的翻译。
TimezoneWidget
在您的 AppView::initialize()
中配置 FormHelper
以使用 TimezoneWidget
。
// src/View/AppView.php public function initialize(): void { $this->loadHelper('Form', [ 'widgets' => [ 'timezone' => ['ADmad/I18n.Timezone'] ] ]); }
您可以使用类似以下方式生成一个包含时区标识符的下拉框:
// Generates select box with list of all timezone identifiers grouped by regions. $this->Form->control('fieldname', ['type' => 'timezone']); // Generates select box with list of timezone identifiers for specified regions. $this->Form->control('fieldname', [ 'type' => 'timezone', 'options' => [ 'Asia' => DateTimeZone::ASIA, 'Europe' => DateTimeZone::EUROPE ] ]);
如上例所示,请注意,与普通下拉框不同,现在 options
是一个有效的时区区域关联数组,其中键将用于在 select 框中使用 optgroup
。