如何在多语言数据库模型中使用Yii?
我在从我的数据库中获取数据时遇到问题,我创建的数据完全是多语言的,我希望这里有人能帮助我。
我把所有的桌子分成两部分, “通用”表(不包含任何需要翻译的文本)以及包含需要翻译的所有字段的表。
示例表格:
base_material
id
picture
base_material_i18n
base_material_id
localization_id
name
description
review_status
review_notes
localization
id
language_name
查询以获取翻译(如果没有可用的翻译,请使用英语(en)作为后备语言):
SELECT o.id
, o.type
, o.code
, o.position
, ifnull(t.name,d.name) name
, ifnull(t.description,d.description) description
FROM base_material o
INNER JOIN base_material_i18n d
ON ( o.id=d.base_material_id)
LEFT OUTER JOIN base_material_i18n t
ON ( d.base_material_id=t.base_material_id AND t.localization_id='nl' )
WHERE d.localization_id='en'
我的问题是,当我搜索base_material对象时,如何在Yii中自动将这些翻译(使用此查询中的回退语言)附加到我的模型中? (这只是一个示例表,但几乎所有的表(20+)都是以这种方式构建的,所以如果可能的话,我会需要灵活的东西)
现有系统使用我需要的一个例子是Propel:http://propel.posterous.com/propel-gets-i18n-behavior-and-why-it-matters
任何想法如何去做呢? 我已经检查了关于多语言站点(如多语言活动记录)的现有Yii扩展,但它们都使用不同的数据库设计(主表中的一般信息+回退语言,国际化表中的翻译),而我不知道如何更改这些扩展以使用我的数据库模型。
如果有人知道改变现有扩展名的方法,以便使用我的数据库方案,那么这绝对是非常出色的,也许是实现这一目标的最佳方式。
编辑:我添加了一个赏金,因为我仍然无法找到任何关于如何让Propel与Yii一起工作的东西(它确实存在对Doctrine的扩展,但Doctrine不支持这种带有翻译的DB模型),也没有有关如何使用现有的Yii扩展或范围来处理这个问题的更多信息。
编辑 :98次浏览,但只有3个upvotes和1评论。 我不禁感到自己在这里做错了什么,无论是在我的问题还是应用程序/数据库设计中; 无论是我的问题还是我的问题都非常独特(这会让我感到惊讶,因为我不认为我的多语言数据库设计是荒谬的;-)。 因此,如果有人知道Yii和/或Propel的多语言站点更好的全面解决方案(除了由于文本字段的重复,我真的不喜欢的当前扩展)或类似的东西,请告诉我以及。
提前致谢!
我也在寻找一个通用的解决方案来实现Yii模型中的i18n。 最近我为像你这样的项目选择了一个非常类似的数据库模式。 唯一的区别是,我没有使用单独的语言表,我将语言信息存储在i18n表中。
以下解决方案没有自定义SQL语句,但我认为这可以通过关系参数来实现,无论如何,如果您在数据库中使用外键(例如MySQL InnoDB),gii将在您的base_material和base_material_i18n表之间创建关系, 喜欢
class BaseMaterial extends CActiveRecord
public function relations()
{
return array(
'baseMaterialI18ns' => array(self::HAS_MANY, 'base_material_i18n', 'id'),
);
}
class BaseMaterialI18n extends CActiveRecord
public function relations()
{
return array(
'baseMaterial' => array(self::BELONGS_TO, 'base_material', 'id'),
);
}
现在,您可以通过使用对象符号进行关系访问您的翻译。
$model = BaseMaterial::model()->with('baseMaterialI18ns')->findByPk(1);
foreach($model->baseMaterialI18ns AS $translation) {
if ($translation->language != "the language I need") continue:
// do something with translation data ...
}
我想为这些模型创建一个行为或基类,这些模型将作为帮助管理翻译的模型 - 伪代码:
I18nActiveRecord extends CActiveRecord
protected $_attributesI18n;
// populate _attributesI18n on query ...
public function __get($name) {
if(isset($this->_attributesI18n['language_I_need'][$name]))
return $this->_attributesI18n[$name];
else if(isset($this->_attributesI18n['fallback_language'][$name]))
return $this->_attributesI18n[$name];
else
parent::__get();
}
CActiveRecord __get()源码
要找到所需的i18n记录还有很多工作要做,还可以进一步限制with()选项以提高性能并减少PHP侧的解析。
但是,如何确定值可能有不同的用例,例如所有翻译,翻译或回退,无回退(空值)。 情景在这里可能会有所帮助。
PS:我会参加github项目!
你有没有试过http://www.yiiframework.com/extension/i18n-columns/(基于http://www.yiiframework.com/extension/stranslateablebehavior/)?
通过以{field} _ {language code}样式添加新表格字段,然后将原始模型中的翻译字段设置为当前语言在afterFind上的翻译,这是一种替代的,更简单的方法。
实质上,它会让你启动并运行带有可翻译字段的翻译内容,并且“自动”获取翻译的内容,好的和不好的:)。 添加和删除语言(=列)使用迁移完成。
您可以尝试使用简单的多语言CRUD扩展。 使用和修改非常简单。 你只需要添加语言字段到你的表。 只是看看这里的描述:http://all-of.me/yii-multilingual-crud/它处于alpha状态,但尝试了几个项目。 您可以轻松修改它或联系作者修复或添加功能
链接地址: http://www.djcxy.com/p/37439.html