simtecsystem/cakephp-i18n

CakePHP插件,用于国际化的相关工具。

安装次数: 107

依赖者: 0

建议者: 0

安全: 0

星标: 0

关注者: 1

分支: 14

类型:cakephp-plugin

2.0.1 2020-07-13 14:18 UTC

This package is auto-updated.

Last update: 2024-09-12 18:46:53 UTC


README

Build Status Coverage Status Total Downloads License

简介

此插件提供

  • 用于生成和匹配带有语言前缀的URL的路由类。
  • 中间件,它根据URL中的语言前缀使用I18n::setLocale()设置地区,并提供对带有语言前缀的适当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 配置设置为语言前缀,并使用 I18n::setLocale() 调用的值作为 locale

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.
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现在是一个关联数组,其中有效的时区区域用作下拉框中的optgroup键。