如何在多语言数据库模型中使用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

上一篇: How to use Yii with a multilingual database model?

下一篇: Add Navigation Property Manually