admad / cakephp-i18n
一个用于I18n相关工具的CakePHP插件。
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 的默认路由中间件(即 after -> 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
文件中,使得制作用于管理翻译的网页界面变得更加容易。
要使用此类,首先使用插件 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'] ] ]); }
你可以生成一个带有时区标识符的 select box,如下所示:
// 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 ] ]);
如上例所示,请注意,与普通 select box 不同,现在 options
是一个有效的时区区域的关联数组,其中的键将用作 select box 中的 optgroup
。