Active Records通过使用locale命名的加前缀的列也许被国际化,然后使用一个AkActiveRecord功能来处理他们。这个部分将使用一个例子来提供详细的解释。这个例子将从一个没有被国际化的表中提取一个字段,然后将它的值写入 esimerkki 项目中一个国际化的表中(Finnish for example).
我们应该做得第一件事就是定义config/config.php中的AK_ACTIVE_RECORD_DEFAULT_LOCALES in config/config.php.最初,我的配置如下:
define('AK_ACTIVE_RECORD_DEFAULT_LOCALES', 'en,en_us');
I changed it to look like this:
define('AK_ACTIVE_RECORD_DEFAULT_LOCALES', 'en,fi,sv');
我说”should”是因为,如果AK_ACTIVE_RECORD_DEFAULT_LOCALES没有被定义,AkActiveRecord::getAvailableLocales()就不会从Ak::langs()得到值。
这个由[creating-and-running-migrations|creating and running a migration]]来完成。做这些的代码显示在连接部分。 运行migration将会给你创建两个表,mono_langs和 multi_langs。
我们需要为这两个表建立models: 转换到你的项目的根目录。
./script/generate model MonoLang
./script/generate model MultiLang
我们将创建app/controllers/refmt_controller.php。为了访问他,然而,我们需要改变config/routes.php 的第一行来引用他。
$Map->connect('/:controller/:action/:id', array('controller' => 'refmt', 'action' => 'index'));
我们将要做的第一件事情是引用models,书写index方法,然后把这些代码写入到非国际化的mono_langs表中
<?php class RefmtController extends ApplicationController { var $models = 'mono_lang, multi_lang'; function index() { if($this->MonoLang->count() == 0) { $this->populate_mono_lang(); } $this->display_func_results(); $this->populate_multi_lang(); exit; // This is to keep from trying to access a view }
我们没有给怎样迁移这个表加备注,因为我们假设你已经知道怎样去做了。我们显示这些代码是为了让你知道输入到表中的内容。
function populate_mono_lang() { $mono = new $this->MonoLang(array('lang' => 'en','name' => 'municipality')); $mono->save(); $mono = new $this->MonoLang(array('lang' => 'fi','name' => 'kunta')); $mono->save(); $mono = new $this->MonoLang(array('lang' => 'sv','name' => 'kommun')); $mono->save(); }
为了使你明白我们拥有的Active Record思想,我们用显示页面源代码的方式,来展示”get”功能的locale的结果,显示页面源代码。(we'll display the results of locale related “get” functions as shown by Page Source.)
function display_func_results() { $result = array(); $result['available_locales'] = $this->MultiLang->getAvailableLocales(); $result['internationalized_columns'] = $this->MultiLang->getInternationalizedColumns(); $result['locales_for_name_attribute'] = $this->MultiLang->getAttributeLocales('name'); $result['current_locale'] = $this->MultiLang->getCurrentLocale(); print_r($result); }
Array
(
[available_locales] => Array
(
[0] => en
[1] => fi
[2] => sv
)
[internationalized_columns] => Array
(
[name] => Array
(
[0] => en
[1] => fi
[2] => sv
)
)
multi_langs表的字段有fields id, en_name, fi_name, sv_name, updated_at和created_at。在这里我们看到的是en_name, fi_name和sv_name,他们比理解为国际化的列。columns id, updated_at和created_at不会作为国际化的列被识别。注意到Active Record用数组存储相关的国际化的列。
[locales_for_name_attribute] => Array
(
[en] =>
[fi] =>
[sv] =>
)
[current_locale] => en
)
这个功能是读取一个非国家化的表,然后把数据写入到国际化的表中。
function populate_multi_lang() { $mono_langs = $this->MonoLang->find('all'); // $mono_langs is an array of objects $multi = $this->MultiLang; // $multi is an instance of the internationalized table foreach($mono_langs as $mono_lang) { $multi->setAttributeByLocale('name', $mono_lang->name, $mono_lang->lang); } $multi->save(); // The following code shows that the data was written to the table. // The real reason for including it is to demonstrate the getAttributebyLocale function. $result = array(); $result['name_by_locale-en'] = $multi->getAttributeByLocale('name','en'); $result['name_by_locale-fi'] = $multi->getAttributeByLocale('name','fi'); $result['name_by_locale-sv'] = $multi->getAttributeByLocale('name','sv'); print_r($result); } } ?>
下面的代码是在一个数据块中做这样的转换。注释和没有必要的代码已经被移除了。
<?php class RefmtController extends ApplicationController { var $models = 'mono_lang, multi_lang'; function index() { if($this->MonoLang->count() == 0) { $this->populate_mono_lang(); } $this->populate_multi_lang(); exit; } function populate_mono_lang() { $mono = new $this->MonoLang(array('lang' => 'en','name' => 'municipality')); $mono->save(); $mono = new $this->MonoLang(array('lang' => 'fi','name' => 'kunta')); $mono->save(); $mono = new $this->MonoLang(array('lang' => 'sv','name' => 'kommun')); $mono->save(); } function populate_multi_lang() { $mono_langs = $this->MonoLang->find('all'); $multi = $this->MultiLang; foreach($mono_langs as $mono_lang) { $multi->setAttributeByLocale('name', $mono_lang->name, $mono_lang->lang); } $multi->save(); } } ?>
locale是在URL中把locale附加到项目的名字上而建立的。你可以打开一个非国际化的应用程序
http://<host>/esimerkki
国际化的应用程序也许是这样打开
http://<host>/esimerkki/en http://<host>/esimerkki/fi 或者 http://<host>/esimerkki/sv
你也可以用非国际化的应用程序打开一个国际化的应用程序,并且在项目中设置语言,如下:
Ak::lang('fi'); $_SESSION['lang'] = 'fi';
'fi'是当前新的locale。第二行显然需要得到文本来反应新的语言。(I found this on the forum.)当然,如果你做了这些,那你不得不改变所有的locale changes programmatically;你不能够通过在URL上附加locale来访问不同的languages。
在这个例子中,这些代码放置在index() function的开头的右边。
ActiveRecord locale-related 功能在这里没有别讨论的是
setAttributeLocales($attribute [, $values = array()]);
我还没有试图去使用他,但是我认为他可能被用在installer中来创建i18n列。
让自己国际化吧(Go internationalize yourself.)。