neam / yii-i18n-columns
为ActiveRecords提供透明的属性翻译,无需查找表即可翻译字段内容。
Requires
- php: >=5.0.0
- yiisoft/yii: >=1.1.0
Requires (Dev)
- phpunit/phpunit: 3.7.*
This package is not auto-updated.
Last update: 2024-09-24 03:23:25 UTC
README
为ActiveRecords提供透明的语言/区域依赖属性和关系,无需使用查找表来翻译字段内容。
当翻译属性应在活动记录的数据库表中本地化时,例如翻译外键或多语言查找/搜索列时,非常理想。
特性
- 简化项目中的多语言ActiveRecords创建
- 默认自动加载应用程序语言
- 翻译直接存储在模型中,每个语言使用单独的列
- 控制台命令自动创建必要的数据库更改迁移
- 利用Gii代码生成提供翻译工作的CRUD
- 不仅限于翻译 - 任何依赖于语言或区域的属性或关系都可以使用此扩展进行管理
- 当需要本地属性时使用,例如外键,或者能够透明地查找和搜索翻译属性。
限制
仅适用于少量属性/语言,否则会超过行大小和/或列数的数据库限制。对于大量翻译属性,请使用 https://github.com/neam/yii-i18n-attribute-messages 或 mike的translatable行为。
要求
- Yii 1.1或更高版本
- 使用Yii控制台
- 使用Gii(最好是 Gtc)
- MySQL 5.1.10+,SQL Server 2012或类似的新版数据库(用于控制台命令。行为本身支持任何Yii支持的数据库)
设置
下载和安装
确保在您的composer.json中包含以下内容
"repositories":[
{
"type": "vcs",
"url": "https://github.com/neam/yii-i18n-columns"
},
...
],
"require":{
"neam/yii-i18n-columns":"dev-master",
...
},
然后通过composer安装
php composer.phar update neam/yii-i18n-columns
如果您不使用composer,将此项目克隆或下载到 /path/to/your/app/vendor/neam/yii-i18n-columns
将别名添加到main.php和console.php中
'aliases' => array(
...
'vendor' => dirname(__FILE__) . '/../../vendor',
'i18n-columns' => 'vendor.neam.yii-i18n-columns',
...
),
在main.php中导入行为
'import' => array(
...
'i18n-columns.behaviors.I18nColumnsBehavior',
...
),
在console.php中引用翻译命令
'commandMap' => array(
...
'i18n-columns' => array(
'class' => 'i18n-columns.commands.I18nColumnsCommand',
),
...
),
配置多语言模型
1. 将行为添加到您希望具有多语言功能的模型中
public function behaviors()
{
return array(
'i18n-columns' => array(
'class' => 'I18nColumnsBehavior',
/* The multilingual attributes */
'translationAttributes' => array(
'title',
'slug',
'image_id',
'etc',
),
/* Specify multilingual belongsTo relations in the form 'RelatedModel' => array('relationName' => 'foreignKey') */
'multilingualRelations' => array(
'Image' => array('image' => 'image_id'),
),
),
);
}
2. 从命令行创建迁移
./yiic i18n-columns process
在此之前,您应该已经为您的应用程序配置了默认语言($config['language'])和可用语言($config['components']['langHandler']['languages'])。
使用--verbose运行以查看更多详细输出。
3. 应用生成的迁移
./yiic migrate
这将重命名在translationAttributes中定义的字段为fieldname_defaultlanguagecode,并为剩余的语言添加列。
示例迁移文件
<?php
class m130708_165204_i18n extends CDbMigration
{
public function up()
{
$this->renameColumn('section', 'title', 'title_en');
$this->renameColumn('section', 'slug', 'slug_en');
$this->addColumn('section', 'title_sv', 'varchar(255) null');
$this->addColumn('section', 'slug_sv', 'varchar(255) null');
$this->addColumn('section', 'title_de', 'varchar(255) null');
$this->addColumn('section', 'slug_de', 'varchar(255) null');
}
public function down()
{
$this->renameColumn('section', 'title_en', 'title');
$this->renameColumn('section', 'slug_en', 'slug');
$this->dropColumn('section', 'title_sv');
$this->dropColumn('section', 'slug_sv');
$this->dropColumn('section', 'title_de');
$this->dropColumn('section', 'slug_de');
}
}
4. 重新生成模型
按照官方文档使用Gii。之后,您将拥有可用的多语言Active Records :)
用法
以下是一个具有多语言 title 属性的Book模型的示例用法。
所有翻译将通过属性后缀提供,例如,英文翻译为$book->title_en,瑞典语翻译为$book->title_sv。 $book->title 将是当前选定语言的翻译的别名。
获取翻译
$book = Book::model()->findByPk(1);
Yii::app()->language = 'en';
echo $book->title; // Outputs 'The Alchemist'
Yii::app()->language = 'sv';
echo $book->title; // Outputs 'Alkemisten'
echo $book->title_en; // Outputs 'The Alchemist'
保存单个翻译
Yii::app()->language = 'sv';
$book->title = 'Djävulen bär Prada';
$book->save(); // Saves 'Djävulen bär Prada' to Book.title_sv
保存多个翻译
$book->title_en = 'The Devil Wears Prada';
$book->title_sv = 'Djävulen bär Prada';
$book->save(); // Saves both translations
更多示例
...可以在tests/unit/I18nColumnsTest.php中找到
变更日志
0.3.1(开发版本)
- 命令操作从模式中删除与未使用的语言相关的列
0.3.0(开发版本)
- 虚拟多语言外键访问(例如 $model->relationName 被映射到 $model->relationNameId{Lang})
- 命令操作从模式中删除与未使用的语言相关的列
- 一些错误修复
0.2.0(最新稳定版)
- 支持多语言外键
- 随着更多语言的添加,逐步添加新的 i18n 列
- 源代码按照 PSR2 标准格式化
0.1.0
- 重命名为 I18nColumns(以阐明底层概念)
- 更精确的模型检测(不搜索模型源文件中的硬编码字符串...)
- 整理干净(不包含完整的 Yii 应用程序,只包含必要的扩展文件)
- Composer 支持
- 改进了 README 中的说明
- 更新以与 Yii 1.1.13 兼容
- 单元测试
0.0.0
致谢
- @firstrow 为创建 STranslateableBehavior,该行为引入了基于列的 i18n 概念,用于 Yii
- @mikehaertl 提供 getter/setter 逻辑
- @schmunk42、@tonydspaniard 和 @Crisu83 提供建议和健康批评
- @clevertech 提供初始测试目录结构
常见问题解答(FAQ)
为什么使用后缀列而不是一个或多个查找表?
1. 与 Gii 和其他 Yii 扩展的兼容性
您的多语言模型将继续作为普通模型工作,尽管比之前多了更多字段。您可以生成新的 CRUD,并立即为所有语言提供翻译界面。
这意味着您将能够在开发周期的早期阶段更快地添加多语言内容。
拥有简单的多语言数据模型可能意味着与其他扩展提供更良好的兼容性,例如提供魔法工具,如保存多对多关系、提供搜索/过滤功能、表单生成器、可编辑的网格视图等。我们的经验表明,这些扩展需要更多自定义,以适应显示相关信息的必要连接数。
2. 您不再依赖于魔法工具(如 ActiveRecord)
不需要创建高级连接助手来访问已翻译的属性,它们一开始就是表中的简单属性。因此,与翻译交互的 SQL 非常直接。
SELECT id, title_en AS title FROM book WHERE title_en = 'The Alchemist';
在您原型化应用程序时,这可能不是一个明显的区别,但当您离开 ActiveRecord 并使用 QueryBuilder、纯 SQL 或与您的 Yii 应用程序一起在裸机 PHP/C 层/应用程序中编写查询时(出于性能原因),它就变得更重要了。
3. 降低复杂性 = 灵活性
假设您有一个查询,在没有翻译字段的情况下需要 7 个连接、一个 group by 子句和 1-2 个子查询。然后添加为每个翻译字段添加一个额外的连接的需求,同时仍然实现高性能查询。这当然是可以的,但会增加复杂性。
本质上,拥有后缀列而不是翻译表的概念类似于代码生成的概念。您为生成代码/数据模型添加了额外的复杂性,但您得到了易于维护和定制的代码库的好处。
4. 为什么不?
参见上面的“局限性”。
此外,如果系统一旦发布就应该是开发者无关的,那么动态添加语言将需要使用类似的脚本来自动化
#!/bin/bash
./yiic i18n-columns
./yiic migrate
./path/to/giic generate application.config.giic.crud
总的来说,这可能不适合目标为简单翻译前端的大型项目,但当主要目标是快速构建功能齐全的后端来管理和翻译多语言内容时,它将更加合适,尤其是数据模型经常发生变化的情况。在开发此类解决方案时,迁移和CRUD生成是日常工作流程的一部分,而生成的代码的简洁性和易于定制往往比开发者的独立性更重要。
运行测试
cd vendor/neam/yii-i18n-columns
php path/to/composer.phar install --dev
cd tests
../vendor/bin/phpunit --verbose --debug
这将产生类似于以下输出的结果:
PHPUnit 3.7.22 by Sebastian Bergmann.
Configuration read from /path/to/app/vendor/neam/yii-i18n-columns/tests/phpunit.xml
Starting test 'I18nColumnsTest::ensureEmptyDb'.
.
Starting test 'I18nColumnsTest::getWithoutSuffix'.
.
Starting test 'I18nColumnsTest::setWithoutSuffix'.
.
Starting test 'I18nColumnsTest::saveSingleWithoutSuffix'.
.
Starting test 'I18nColumnsTest::fetchSingleWithoutSuffix'.
.
Starting test 'I18nColumnsTest::saveMultiple'.
.
Time: 0 seconds, Memory: 10.00Mb
OK (6 tests, 28 assertions)