我正在慢慢学习如何应用CakePHP的翻译行为,我想我已经掌握了基础知识,但我正在使用现有的数据进行一个现有的项目。Cake将为我插入新记录,这很棒,但我需要手动(假设)为一些现有数据插入一些翻译。我的第一个问题:
如果en_us是我的默认语言,也是我的核心表中使用的语言,那么我的i18n表中是否必须有一条en_us的记录?例如,如果categories.name = 'Entertainment',我真的需要在i18n中创建一个"duplicate“记录来指明"Entertainment”的英文翻译吗?经验证据似乎是肯定的,但这似乎需要很多额外的工作,所以我希望有人能告诉我,我遗漏了一些东西。
其次,有没有一种“简单”的方法将翻译记录放入数据库?随着在项目过程中添加语言,返回并为遗留数据创建i18n记录将是非常痛苦的。
谢谢。
发布于 2009-04-16 08:07:31
我对第二个问题没有答案,但第一个问题的答案似乎是“是的”。在深入研究源代码之后,生成的查询的where子句似乎将结果限制为正在检索的字段名称具有当前区域设置的区域设置值的结果。这是非常有限的。
对此有一个existing ticket (或者非常类似的东西)。
发布于 2012-05-04 10:30:50
我知道这是旧的,但由于它没有回答,我遇到了一些麻烦,这是我的两点意见:
scope,Cakephp 1.3。
首先,您需要为应用程序中的每个字段->记录->模型创建一个i18n记录,当然只需要具有Translate行为的模型和指定字段,因此,是的,您将在实际模型字段和i18n表中得到重复的内容。
此外,对于您指定的任何语言,都需要现有的翻译,以便find方法返回任何内容。这把我搞糊涂了,因为我还在一个已经开发的项目中添加了翻译行为,有大量的数据。基本上,我所做的是创建一个sync方法,以便使用翻译行为为每个模型的每个字段创建每个翻译。如果我将来添加一种新的语言,我将不得不再次运行它。
下面是实现该功能的代码:
$locales = array( 'spa', 'eng', 'por' );
$models = array( 'Event', 'News', 'Promotion', 'Shop', 'ShopCategory' );
foreach ( $models as $model )
{
$this->loadModel( $model );
$records = $this->{$model}->find( 'all', array(
'fields' => array( "*" ),
'contain' => FALSE
) );
$fields = $this->{$model}->actsAs['Translate'];
foreach ( $records as $record )
{
foreach ( $fields as $field )
{
foreach ( $locales as $locale )
{
$content = mysql_real_escape_string( $record[$model][$field] );
$this->{$model}->query( "INSERT INTO `i18n` (`locale`, `model`, `foreign_key`, `field`, `content`) VALUES('{$locale}', '{$model}', '{$record[$model]['id']}', '{$field}', '{$content}');" );
}
}
}
}提示:使用语言环境、型号、foreign_key和字段键在i18n表中创建唯一索引。
因此,现在我已经用所有语言复制了原始数据,我需要能够使用给定语言创建新记录。问题是,如果我用英语创建一个新的记录,我应该能够用西班牙语更新它,但是因为没有西班牙语的i18n记录,我在我的内容管理系统中看不到记录,也不能编辑它。我解决这个问题的方法是在创建新记录时为每种语言创建i18n记录,但在编辑记录时只使用当前语言进行编辑。
我对翻译行为使用了以下修改:http://bin.cakephp.org/view/1939852942
但是这个修改的大多数示例表明,您必须在表单中创建表单输入: echo $ this ->表单->输入(‘name.eng’);echo $this->表单->输入(‘name.spa’);echo $this->表单->输入(‘description.eng’);echo $this->表单->输入(‘description.spa’);
我觉得这很烦人,所以我基本上在app_controller中做了一个助手函数,将可翻译的字段转换成这个数据结构:
function _expandLocalizations( $data )
{
foreach ( $data as $modelName => $modelData )
{
if ( !isset( $modelData[$this->{$modelName}->primaryKey] ) )
{
foreach ( $this->{$modelName}->actsAs['Translate'] as $field )
{
$translations = array();
foreach ( $this->languages as $language )
{
$translations[$language] = $this->data[$modelName][$field];
}
$data[$modelName][$field] = $translations;
}
}
}
return $data;
}在每个add方法中:
if ( !empty( $this->data ) )
{
$this->News->set( $this->data );
if ( $this->News->validates() )
{
$this->News->create();
$data = $this->_expandLocalizations( $this->data );
$saved = $this->News->save( $data );
if ( $saved )
{这样我就可以使用传统的表单,如果我添加了新的语言,我就不需要改变视图了。我需要修改传统的baked add方法,因为我需要提交的数据用于验证,但修改后的数据用于保存。
最后,我按照以下步骤更改了站点/admin:http://nuts-and-bolts-of-cakephp.com/2008/11/28/cakephp-url-based-language-switching-for-i18n-and-l10n-internationalization-and-localization/中的语言
所以基本上就是这样了。1.为数据库中已有的每个数据创建翻译,每个翻译都复制到每种语言。2.在create中为新记录创建每个翻译,当然,所有翻译都具有相同的值。3.编辑选定翻译中的每条记录。
发布于 2012-05-16 04:44:49
至于第一个问题,答案是否定的。不需要重复的数据,尽管我一开始也这么认为。
我已经写了一篇关于它的博客文章来帮助你在那里迷失的灵魂。http://kristofferdarj.se/2012/05/cakephp-how-to-actually-use-i18n/
https://stackoverflow.com/questions/744802
复制相似问题