问题
I'm newbie to Yii. Official documentation does not give any examples for CDbMessageSource. Questions: 1) How/Where do I set CDbMessageSource as my MessageSource ?
2) In my current application I store Categories in one table and translations for Categories in other table. Tables structure:
CATEGORY
----------
cat_id (PK)
CATEGORY_TRANSLATION
--------------------
cat_id (FK)
en
ru
Now if I introduce sub-categories I would model DB this way:
SUB_CATEGORY
------------
sub_cat_id (PK)
cat_id (FK)
SUB_CATEGORY_TRANSLATION
------------------------
sub_cat_id (FK)
en
ru
Do I understand it correctly that in Yii if I want to use CDbMessageSource to store translations then I would need to merge CATEGORY & SUB_CATEGORY in to one table , then merge CATEGORY_TRANSLATION & SUB_CATEGORY_TRANSLATION in to other so that in result I get following structure (taken from here 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
);
Thank you !
回答1:
How to enable CDbMessageSource
The message source is an application component with the name "messages". Therefore you configure it just like any other component in your application configuration file:
array(
......
'components'=>array(
......
'messages'=>array(
'class'=>'CDbMessageSource',
// additional parameters for CDbMessageSource here
),
),
),
)
The message source and localizable models -- not an ideal relationship
It's important to keep in mind that the message source only provides translations for known messages. It does not make much sense to involve the message source in your model localization because how would you utilize it?
Assume you have a category with id = 1
. How would you get its localized title? Something like Yii::t('category', 'title_'.$category->id)
could work, but it's somewhat clumsy (not desirable syntax, you have to "bake in" your primary key information into your display code, etc). If your title localizations are also meant to be modifiable by users this is going to get even more complicated. (In any case, if you wanted to do this then merging the two translation tables and using a separate value when populating SourceMessage.category
would be the way to go).
An alternative approach to localizing models
Here's a brief rundown of how you can conveniently localize your models. Let's say we have a Room
model with a localizable name
property. You can create a new table named LocalizedString
and the corresponding model that has a structure similar to this:
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`),
);
Then, configure your Room
model with a relation on LocalizedString
:
public function relations()
{
$localeCode = Yii::app()->getLanguage();
return array(
'nameStringTemplate' => array(
self::BELONGS_TO, 'LocalizedString', 'NameStringTemplateId',
'condition' => 'nameStringTemplate.LocaleCode = \''.$localeCode.'\''),
);
}
And add a read-only property:
public function getName() {
return $this->nameStringTemplate->StringTemplate;
}
By doing this, you can now write $room->name
anywhere and you will automagically get back the localized translation for the application's current language.
There are many details that need to be taken care of and that I have glossed over here, but the idea should be apparent.
来源:https://stackoverflow.com/questions/11760954/yii-localisation-cdbmessagesource-example