dlds / yii2-translate-manager

在线翻译

2.0.8 2017-09-03 18:22 UTC

README

在线翻译

简介

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

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

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

安装

安装此扩展的首选方式是通过 composer

运行以下命令:

php composer.phar require --prefer-dist lajax/yii2-translate-manager "1.*"

或者

"lajax/yii2-translate-manager": "1.*"

将以下内容添加到您的 composer.json 文件的 require 部分。

###迁移

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

Linux/Unix

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

Windows

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

###配置

以下是一个开启 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.
        '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',
        ],
        'googleApiKey' => 'your_google_API_Key', // if set - google translation will be inserted into translation field when you click on the source field.  
    ],
],

配置扫描根目录

根路径可以是别名或完整路径(例如 @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 版起)

    注意: 这将替换模型的原始属性值!

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(),
            // ],
        ];
    }

}

### URL

翻译工具的 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

### 使用 Google 翻译 API

Google 翻译 API 是一项付费服务。撰写本文时,每 1,000,000 个字符翻译的价格为 20 美元。

要激活此功能,您需要 Google 帐户,生成 Google API 密钥,并在 'translatemanager' 模块配置中添加 'googleApiKey'。

'modules' => [

    'translatemanager' => [
    
        // ...
        
        'googleApiKey' => `Your_Google_API_Key',
     ],
],

一旦功能启用,当您单击源字段时,它将插入源字段的 Google 翻译而不是原始文本。

已知问题

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

    您可以通过 scanRootParentDirectory 选项覆盖此行为。(有关详细信息,请参阅配置部分。)

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

编码风格

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

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

composer cs-fix

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

composer cs-fix-dry-run

屏幕截图

### 语言列表 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

链接