作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
首先,我们来看站点名称的翻译,我们站点的名称为“亚艾元”,在英文环境下,我们想显示拼音的形式。怎么翻译呢?导航到admin/config/system/site-information,这是站点名称所在的配置界面:
在这个页面的上面有提示,这个表单中包含多语言的变量,我们将它切换到英文的环境下,admin/config/system/site-information?variable_realm_key_language=en,在这种情况下,输入拼音,保存:
此时,我又遇到了一个问题,那就是虽然我这里输入了变量的英文版本,但是在首页的中英文切换的过程中,站点名称始终是中文。我尝试了比较多的办法,比如分别使用路经:zh-hans/admin/config/system/site-information,和en/admin/config/system/site-information访问,然后输入对应的中文、英文版本,还是不行。
我Google 了一下,找到一篇文档,https://drupal.org/node/1113374,这里讲的就是变量翻译,我的配置没有任何问题。通过这篇文章,我了解到admin/config/regional/i18n的存在,这是i18n的配置界面,变量的多语言设置可以在admin/config/regional/i18n/variable完成。
然后我想到了在预处理函数中,搞定这个问题,在当前主题的template.php文件中添加这么一个函数:
function yaiyuan_preprocess_page(&$variables, $hook) {
global $language;
$lang_name = $language->language ;
$variables['site_name'] = (theme_get_setting('toggle_name') ? filter_xss_admin(i18n_variable_get('site_name', 'en')) : '');
drupal_set_message($lang_name);
}
注意,这里的$lang_name始终都是zh-hans,即便是我切换到了英文下面。我这里使用i18n_variable_get来替代默认的variable_get,以便支持多语言。
昨天晚上一直在想解决方案,如果我能够获取到当前语言,那么通过预处理函数的方式,就能够解决问题,Drupal核心自带的语言切换器区块对应的代码里面,应该有如何获取当前语言的代码。这样一想,感觉问题是可以通过预处理函数的方式解决的。
不过,我突然想到了一件事情,即便是使用en/admin/config/system/site-information访问后台页面的时候,后台显示的也是简体中文。我突然想到,Drupal7中,界面语言和内容语言的检测方法是分开配置的,界面语言的检测方法我们还是用的默认的,很可能是这里出了问题。
我们先沿着第一种方案继续前进,我们去配置“语言切换器(内容)”的时候,可以看出这个区块是由locale模块提供的,这样我们就可以顺藤摸瓜,找到对应的代码。
function locale_block_view($type) {
if (drupal_multilingual()) {
$path = drupal_is_front_page() ? '<front>' : $_GET['q'];
$links = language_negotiation_get_switch_links($type, $path);
这里面,我觉得比较关键是language_negotiation_get_switch_links,通过搜索,找到这个函数的源代码。在这个函数里面,有这么一段代码:
if (count(language_list()) >= 2) {
$language = language_initialize($type);
}
给了我很大的提示,这里的$type有多种情况,我们在前面分析核心源代码的时候,曾经提到过,打开bootstrap.inc文件,找到:
define('LANGUAGE_TYPE_CONTENT', 'language_content');
/**
* The type of language used to select the user interface.
*/
define('LANGUAGE_TYPE_INTERFACE', 'language');
/**
* The type of language used for URLs.
*/
define('LANGUAGE_TYPE_URL', 'language_url');
我们这里使用LANGUAGE_TYPE_CONTENT。根据这些信息,我最终使用下面的代码,解决了这个多语言问题:
function yaiyuan_preprocess_page(&$variables, $hook) {
//global $language;
//$lang_name = $language->language ;
$language = language_initialize(LANGUAGE_TYPE_CONTENT);
$variables['site_name'] = (theme_get_setting('toggle_name') ? filter_xss_admin(i18n_variable_get('site_name', $language->language)) : '');
//drupal_set_message($lang_name);
//print debug($language);
}
这里面,如何获取当前语言,我首先尝试了一下$language,总是不对。使用language_initialize(LANGUAGE_TYPE_CONTENT),则可以成功获取。注意我们这里获取的是当前内容的语言。不是当前的界面语言。此外,我对这个语言变量还debug了一下,查看了它的结构。它的结构是这个样子的:
stdClass::__set_state(array(
'language' => 'en',
'name' => 'English',
'native' => 'English',
'direction' => '0',
'enabled' => '1',
'plurals' => '0',
'formula' => '',
'domain' => '',
'prefix' => 'en',
'weight' => '0',
'javascript' => '',
'provider' => 'locale-url',
))
我们使用预处理函数的方式解决了问题。不过,总不能每次都这样解决吧。或许真的是界面语言的检测与选择的配置问题。导航到admin/config/regional/language/configure,对于界面语言的检测方法,我们与内容的保持一致。
保存这里的配置。注释掉,我们前面所写的预处理函数。站点名称的中英文切换,正常。当然,前面的工作,也不是没有白做,如果你跟着阅读了源代码,会对Drupal7多语言的背后机制有更深的理解。比如这个语言,它分为:内容、界面、路径。我们这里对这个概念有了更深的理解。我们前面的获取当前语言,其实是获取当前内容语言,而不是获取当前界面语言。
如果,我们这里是一个Logo,中文Logo和英文Logo不一样,怎么解决呢?导航到zh-hans/admin/config/regional/i18n/variable,
选中这里的主题设置复选框即可,这样主题的Logo就支持多语言了,分别为每个语言上传一个Logo,解决了Logo的多语言问题。