admad/cakephp-i18n

CakePHP 的 I18n 工具插件。

资助包维护!
ADmad

安装: 23,084

依赖者: 0

建议者: 0

安全: 0

星标: 43

关注者: 9

分支: 14

开放问题: 1

类型:cakephp-plugin

3.0.0 2023-09-29 06:08 UTC

This package is auto-updated.

Last update: 2024-08-29 08:08:54 UTC


README

Build Status Coverage Status Total Downloads License

简介

此插件提供

  • 用于生成和匹配带有语言前缀的 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)))之后添加此中间件。

中间件主要执行以下两项操作

  1. 当访问网站根目录 / 时,它将用户重定向到带有语言前缀的 URL,例如 /en。重定向到的语言取决于上述配置键 detectLanguagedefaultLanguage

    现在,为了防止 CakePHP 抱怨 / 的路由缺失,您必须将一个路由连接到 /,该控制器动作永远不会实际调用,因为中间件将拦截并重定向请求。

    例如,$routes->connect('/', ['controller' => 'Foo']);

  2. 当访问任何带有语言前缀的 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