我是Yii的新手。官方文档没有给出CDbMessageSource的任何示例。 问题: 1)如何/在哪里将CDbMessageSource设置为我的MessageSource?
2)在我当前的应用程序中,我将类别存储在一个表中,并将类别的翻译存储在其他表中。表结构:
CATEGORY
----------
cat_id (PK)
CATEGORY_TRANSLATION
--------------------
cat_id (FK)
en
ru
现在,如果我介绍子类别,我会用这种方式建模DB:
SUB_CATEGORY
------------
sub_cat_id (PK)
cat_id (FK)
SUB_CATEGORY_TRANSLATION
------------------------
sub_cat_id (FK)
en
ru
我是否理解正确在Yii如果我想使用CDbMessageSource存储翻译,那么我需要合并CATEGORY&将SUB_CATEGORY放入一个表中,然后合并CATEGORY_TRANSLATION&将SUB_CATEGORY_TRANSLATION转入其他内容,以便结果我获得以下结构(取自此处http://www.yiiframework.com/doc/api/1.1/CDbMessageSource):
CREATE TABLE SourceMessage
(
id INTEGER PRIMARY KEY,
category VARCHAR(32),
message TEXT
);
CREATE TABLE Message
(
id INTEGER,
language VARCHAR(16),
translation TEXT,
PRIMARY KEY (id, language),
CONSTRAINT FK_Message_SourceMessage FOREIGN KEY (id)
REFERENCES SourceMessage (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
谢谢!
答案 0 :(得分:3)
CDbMessageSource
消息来源是application component,名称为“messages”。因此,您可以像配置应用程序配置文件中的任何其他组件一样对其进行配置:
array(
......
'components'=>array(
......
'messages'=>array(
'class'=>'CDbMessageSource',
// additional parameters for CDbMessageSource here
),
),
),
)
请务必记住,消息源仅提供已知消息的翻译。将消息源置于模型本地化中没有多大意义,因为您将如何利用它?
假设您有一个id = 1
的类别。你会如何获得其本地化的头衔?像Yii::t('category', 'title_'.$category->id)
这样的东西可以工作,但它有些笨拙(不太理想的语法,你必须将你的主键信息“烘焙”到你的显示代码中等)。如果您的标题本地化也可以由用户修改,那么这将变得更加复杂。 (无论如何,如果你想这样做,那么合并两个转换表并在填充SourceMessage.category
时使用一个单独的值就可以了。)
以下是您如何方便地本地化模型的简要说明。假设我们的Room
模型具有可本地化的name
属性。您可以创建一个名为LocalizedString
的新表以及具有与此类似结构的相应模型:
CREATE TABLE IF NOT EXISTS `localized_string` (
`Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`LocaleCode` char(5) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`StringTemplate` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`Id`,`LocaleCode`),
);
然后,使用Room
:
LocalizedString
模型
public function relations()
{
$localeCode = Yii::app()->getLanguage();
return array(
'nameStringTemplate' => array(
self::BELONGS_TO, 'LocalizedString', 'NameStringTemplateId',
'condition' => 'nameStringTemplate.LocaleCode = \''.$localeCode.'\''),
);
}
添加只读属性:
public function getName() {
return $this->nameStringTemplate->StringTemplate;
}
通过这样做,您现在可以在任何地方编写$room->name
,您将自动获取应用程序当前语言的本地化翻译。
有许多细节需要注意,我已经在这里掩饰了,但这个想法应该是显而易见的。