lajax/yii2-translate-manager

Yii 2的翻译管理扩展

安装量: 462,553

依赖者: 17

建议者: 0

安全: 0

星级: 227

关注者: 21

分支: 90

开放性问题: 39

类型:yii2-extension

1.8.1 2020-07-04 07:19 UTC

README

Latest Version on Packagist Software License Total Downloads

Yii 2的翻译管理扩展

简介

此模块为项目的多语言元素提供简单的翻译界面。它可以自动检测新的语言元素(项目扫描)。在项目扫描期间自动过滤重复项。可以通过单击一次从数据库中删除未使用的语言元素(数据库优化),并可以导入和导出翻译。还可以翻译客户端消息(存储在JavaScript文件中的消息),因为项目扫描还会从JavaScript文件收集要翻译的语言元素。

它还允许您在不登录翻译界面的情况下翻译客户端上的文本(在实时网页上)。 (前端翻译)。

在服务器端,它可以处理数据库或一维/多维数组元素和Yii::t函数。可以排除文件、文件夹或类别以防止它们被翻译。

贡献

请阅读并遵循贡献指南中的说明。

安装

通过Composer

composer require lajax/yii2-translate-manager

迁移

在终端中运行以下命令进行数据库迁移

yii migrate/up --migrationPath=@vendor/lajax/yii2-translate-manager/migrations

或使用命名空间迁移(需要至少Yii 2.0.10)

// Add namespace to console config:
'controllerMap' => [
    'migrate' => [
        'class' => 'yii\console\controllers\MigrateController',
        'migrationNamespaces' => [
            'lajax\translatemanager\migrations\namespaced',
        ],
    ],
],

然后运行

yii migrate/up

配置

开启Yii数据库多语言的一个简单示例。

'language' => 'en-US',
'components' => [
    'i18n' => [
        'translations' => [
            '*' => [
                'class' => 'yii\i18n\DbMessageSource',
                'db' => 'db',
                'sourceLanguage' => 'xx-XX', // Developer language
                'sourceMessageTable' => '{{%language_source}}',
                'messageTable' => '{{%language_translate}}',
                'cachingDuration' => 86400,
                'enableCaching' => true,
            ],
        ],
    ],
],

开启TranslateManager模块

简单示例

'modules' => [
    'translatemanager' => [
        'class' => 'lajax\translatemanager\Module',
    ],
],

以下是一个更复杂的示例,包括支持多语言的数据表

'modules' => [
    'translatemanager' => [
        'class' => 'lajax\translatemanager\Module',
        'root' => '@app',               // The root directory of the project scan.
        'scanRootParentDirectory' => true, // Whether scan the defined `root` parent directory, or the folder itself.
                                           // IMPORTANT: for detailed instructions read the chapter about root configuration.
        'layout' => 'language',         // Name of the used layout. If using own layout use 'null'.
        'allowedIPs' => ['127.0.0.1'],  // IP addresses from which the translation interface is accessible.
        'roles' => ['@'],               // For setting access levels to the translating interface.
        'tmpDir' => '@runtime',         // Writable directory for the client-side temporary language files.
                                        // IMPORTANT: must be identical for all applications (the AssetsManager serves the JavaScript files containing language elements from this directory).
        'phpTranslators' => ['::t'],    // list of the php function for translating messages.
        'jsTranslators' => ['lajax.t'], // list of the js function for translating messages.
        'patterns' => ['*.js', '*.php'],// list of file extensions that contain language elements.
        'ignoredCategories' => ['yii'], // these categories won't be included in the language database.
        'onlyCategories' => ['yii'],    // only these categories will be included in the language database (cannot be used together with "ignoredCategories").
        'ignoredItems' => ['config'],   // these files will not be processed.
        'scanTimeLimit' => null,        // increase to prevent "Maximum execution time" errors, if null the default max_execution_time will be used
        'searchEmptyCommand' => '!',    // the search string to enter in the 'Translation' search field to find not yet translated items, set to null to disable this feature
        'defaultExportStatus' => 1,     // the default selection of languages to export, set to 0 to select all languages by default
        'defaultExportFormat' => 'json',// the default format for export, can be 'json' or 'xml'
        'tables' => [                   // Properties of individual tables
            [
                'connection' => 'db',   // connection identifier
                'table' => '{{%language}}',         // table name
                'columns' => ['name', 'name_ascii'],// names of multilingual fields
                'category' => 'database-table-name',// the category is the database table name
            ]
        ],
        'scanners' => [ // define this if you need to override default scanners (below)
            '\lajax\translatemanager\services\scanners\ScannerPhpFunction',
            '\lajax\translatemanager\services\scanners\ScannerPhpArray',
            '\lajax\translatemanager\services\scanners\ScannerJavaScriptFunction',
            '\lajax\translatemanager\services\scanners\ScannerDatabase',
        ],
    ],
],

配置扫描根目录

根路径可以是别名或完整路径(例如 @app/webroot/site/)。

文件扫描器将扫描配置的文件夹以查找可翻译元素。以下两个选项确定扫描根目录:rootscanRootParentDirectory。这些选项的默认值适用于Yii 2高级项目模板。如果您使用的是基本模板,则必须修改这些设置。

root 选项指定项目扫描的根文件夹。它可以包含单个目录(字符串),或多个目录(数组)。

scanRootParentDirectory 只在指定单个根目录为字符串时使用。

重要:更改这些选项可能会导致翻译项目丢失,因为优化操作会删除丢失的项目。因此,请务必仔细检查您的配置!

a) 单个根目录

可以在root选项中将一个根目录定义为字符串。在这种情况下,将使用scanRootParentDirectory来确定实际要扫描的目录。

如果将scanRootParentDirectory设置为true(这是默认值),则扫描将在父目录上运行。这是高级模板中所需的行为,因为@app是当前应用程序的根,它是项目中的一个子文件夹(因此项目的整个根目录是@app的父目录)。

对于基本模板,@app也是整个项目的根。由于这个原因,默认值下的scanRootParentDirectory会导致扫描在项目文件夹之外运行。这不是所需的行为,将值更改为false可以解决这个问题。

重要:scanRootParentDirectorytrue更改为false可能会导致翻译项目丢失,因为根目录将不同。

例如:

b) 多个根目录

可以在数组中定义多个根目录。在这种情况下,所有项目都必须指向确切的目录,因为 scanRootParentDirectory 将被省略

例如:

'root' => [
    '@frontend',
    '@vendor',
    '/some/external/folder',
],

使用 authManager

示例

PhpManager

'components' => [
    'authManager' => [
        'class' => 'yii\rbac\PhpManager',
    ],
    // ...
],

DbManager

'components' => [
    'authManager' => [
        'class' => 'yii\rbac\DbManager',
    ],
    // ...
],

前端翻译

'bootstrap' => ['translatemanager'],
'components' => [
    'translatemanager' => [
        'class' => 'lajax\translatemanager\Component'
    ]
]

用法

注册客户端脚本

要翻译JavaScript文件中的静态消息,需要注册这些文件。

要注册您的脚本,请在每个操作中调用以下方法

\lajax\translatemanager\helpers\Language::registerAssets();

在每次页面加载时调用上述方法的简单示例

namespace common\controllers;

use lajax\translatemanager\helpers\Language;

// IMPORTANT: all Controllers must originate from this Controller!
class Controller extends \yii\web\Controller {

    public function init() {
        Language::registerAssets();
        parent::init();
    }
}

切换翻译按钮

显示用于切换到前端翻译模式的按钮的简单示例。(按钮只会出现在具有必要翻译权限的用户面前!)

\lajax\translatemanager\widgets\ToggleTranslate::widget();

显示按钮的更复杂示例

\lajax\translatemanager\widgets\ToggleTranslate::widget([
 'position' => \lajax\translatemanager\widgets\ToggleTranslate::POSITION_TOP_RIGHT,
 'template' => '<a href="javascript:void(0);" id="toggle-translate" class="{position}" data-language="{language}" data-url="{url}"><i></i> {text}</a><div id="translate-manager-div"></div>',
 'frontendTranslationAsset' => 'lajax\translatemanager\bundles\FrontendTranslationAsset',
 'frontendTranslationPluginAsset' => 'lajax\translatemanager\bundles\FrontendTranslationPluginAsset',
]);

在源代码中放置多语言元素。

JavaScript

lajax.t('Apple');
lajax.t('Hello {name}!', {name:'World'});
lajax.t("Don't be so upset.");

PHP方法

Yii::t('category', 'Apple');
Yii::t('category', 'Hello {name}!', ['name' => 'World']);
Yii::t('category', "Don't be so upset.");

PHP前端翻译函数

use lajax\translatemanager\helpers\Language as Lx;

Lx::t('category', 'Apple');
Lx::t('category', 'Hello {name}!', ['name' => 'World']);
Lx::t('category', "Don't be so upset.");

重要提示:当前,lajax\translatemanager\helpers\Language::t()(Lx::t())函数不支持HTML属性的翻译。

PHP数组

/**
 * @translate
 */
private $_STATUSES = [
    self::STATUS_INACTIVE => 'Inactive',
    self::STATUS_ACTIVE => 'Active',
    self::STATUS_DELETED => 'Deleted'
];

/**
 * Returning the 'status' array on the site's own language.
 * return array
 */
public function getStatuses() {
    return \lajax\translatemanager\helpers\Language::a($this->_STATUSES);
}

/**
 * @translate
 */
private $_GENDERS = ['Male', 'Female'];

/**
 * Returning the 'genders' array in German
 * return array
 */
public function getGenders() {
    return \lajax\translatemanager\helpers\Language::a($this->_GENDERS, 'de-DE');
}

PHP数据库

  • 带有新属性
namespace common\models;

use lajax\translatemanager\helpers\Language;

/**
 * This is the model class for table "category".
 *
 * @property string $category_id
 * @property string $name
 * @property string $description
 */
class Category extends \yii\db\ActiveRecord {

    // afterFind & beforeSave:

    /**
     * @var Returning the 'name' attribute on the site's own language.
     */
    public $name_t;

    /**
     * @var Returning the 'description' attribute on the site's own language.
     */
    public $description_t;

    /* ... */

    public function afterFind() {
        $this->name_t = Language::d($this->name);
        $this->description_t = Language::d($this->descrioption);

        // or If the category is the database table name.
        // $this->name_t = Language::t(static::tableName(), $this->name);
        // $this->description_t = Language::t(static::tableName(), $this->description);
        parent::afterFind();
    }

    public function beforeSave($insert) {
        if (parent::beforeSave($insert)) {
            Language::saveMessage($this->name);
            Language::saveMessage($this->description);

            // or If the category is the database table name.
            // Language::saveMessage($this->name, static::tableName());
            // Language::saveMessage($this->description, static::tableName());

            return true;
        }

        return false;
    }

    // or GETTERS:

    /**
     * @return string Returning the 'name' attribute on the site's own language.
     */
    public function getName($params = [], $language = null) {
        return Language::d($this->name, $params, $language);

        // or If the category is the database table name.
        // return Language::t(static::tableName(), $this->name, $params, $language);
    }

    /**
     * @return string Returning the 'description' attribute on the site's own language.
     */
    public function getDescription($params = [], $language = null) {
        return Language::d($this->description, $params, $language);

        // or If the category is the database table name.
        // return Language::t(static::tableName(), $this->description, $params, $language);
    }
}
  • 带有行为(自1.5.3起)

    此行为执行以下操作

    • 在模型加载后替换指定的属性为翻译。
    • 以以下方式保存属性值
      1. 源消息,如果当前语言是源语言。
      2. 翻译,如果当前语言不同于源语言。这样,存储在数据库中的值不会被翻译覆盖。

    注意:如果模型应作为翻译保存,但源消息尚未在数据库中存在,则无论当前语言是否是源语言,消息都保存为源消息。为了避免这种情况,在首次使用行为时先扫描数据库中的现有消息,并且仅在当前语言是源语言时保存新记录。

namespace common\models;

/**
 * This is the model class for table "category".
 *
 * @property string $category_id
 * @property string $name
 * @property string $description
 */
class Category extends \yii\db\ActiveRecord {

    // TranslateBehavior

    public function behaviors()
    {
        return [
            [
                'class' => \lajax\translatemanager\behaviors\TranslateBehavior::className(),
                'translateAttributes' => ['name', 'description'],
            ],

            // or If the category is the database table name.
            // [
            //     'class' => \lajax\translatemanager\behaviors\TranslateBehavior::className(),
            //     'translateAttributes' => ['name', 'description'],
            //     'category' => static::tableName(),
            // ],
        ];
    }

}

URLs

翻译工具的URL

/translatemanager/language/list         // List of languages and modifying their status
/translatemanager/language/create       // Create languages
/translatemanager/language/scan         // Scan the project for new multilingual elements
/translatemanager/language/optimizer    // Optimise the database

将Yii2菜单实现到您自己的菜单中的示例

$menuItems = [
    ['label' => Yii::t('language', 'Language'), 'items' => [
            ['label' => Yii::t('language', 'List of languages'), 'url' => ['/translatemanager/language/list']],
            ['label' => Yii::t('language', 'Create'), 'url' => ['/translatemanager/language/create']],
        ]
    ],
    ['label' => Yii::t('language', 'Scan'), 'url' => ['/translatemanager/language/scan']],
    ['label' => Yii::t('language', 'Optimize'), 'url' => ['/translatemanager/language/optimizer']],
    ['label' => Yii::t('language', 'Im-/Export'), 'items' => [
        ['label' => Yii::t('language', 'Import'), 'url' => ['/translatemanager/language/import']],
        ['label' => Yii::t('language', 'Export'), 'url' => ['/translatemanager/language/export']],
    ]
];

控制台命令

注册命令

'controllerMap' => [
    'translate' => \lajax\translatemanager\commands\TranslatemanagerController::className()
],

使用Yii CLI使用它

./yii translate/scan
./yii translate/optimize

已知问题

  • 扫描器正在扫描父根目录 #12

    您可以使用 scanRootParentDirectory 选项覆盖此行为。(请参阅配置部分以获取详细信息。)

  • 隐藏标签中的字符串的前端翻译会破坏HTML。#45

编码风格

项目使用PSR-2编码标准。

可以使用以下命令修复编码风格问题

composer cs-fix

您可以在不修改代码的情况下检查代码

composer cs-fix-dry-run

变更日志

请参阅 CHANGELOG 了解最近更改的更多信息。

许可证

MIT许可证(MIT)。有关更多信息,请参阅 许可证文件

屏幕截图

语言列表

translate-manager-0 2-screen-1

扫描项目

translate-manager-0 2-screen-2

优化数据库

translate-manager-0 2-screen-3

在管理界面翻译

translate-manager-0 2-screen-4

翻译模式下的前端

translate-manager-0 2-screen-6

在前端翻译

translate-manager-0 2-screen-7

链接