5语言切换器区块

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

我们导航到区块的管理界面,找到“语言切换器(内容)”区块,将它放在主题的“标题”区域中,同时禁用区块标题。默认是这样显示的:

1.png 

我们调整一下CSS

.region-header{

  float:right;

  clear:none;

}

.region-header #block-locale-language-content .language-switcher-locale-url li{

  display:block;

  float:left;

  margin-right:20px;

}

.region-header  a {

    text-decoration: none;

}

这是调整后的样子:

2.png 

值得一提的是,如果把新闻翻译好了以后,在新闻列表页面的英文版本下,显示也是基本正常的,这是en/news/4路经下的样子:

3.png 

除了节点和分类术语以外,我们还有很多工作要做,比如菜单、区块、系统变量,字段的标签,等等,需要翻译。


Drupal版本:

5.1 i18n模块

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

我们下载、安装、启用i18n模块,我这里使用的版本是i18n-7.x-1.9。这个模块还依赖于Variable模块,我们还需要先安装Variable模块,我这里使用的版本是variable-7.x-2.2。 i18n模块下面包含很多个子模块,从上到下:

1.png 

我这里启用了Block languagesField translationInternationalization,这里的Contact translation是负责Contact这个核心模块的翻译的,不过我们这个站点没有用到这个模块。

2.png 

这里,我启用了Menu translation模块;Multilingual content这个是基于content translation的,我们这里没有采用这种方案;Multilingual forum解决的是论坛模块的翻译,我们这里没有使用论坛模块;Multilingual select,这个可能有用,后面我们不妨启用测试一下,看是否能够解决我们前面所说的分类术语选择时的问题。

3.png 

这里,启用了String translationSynchronize translations是基于content translation的,我们这里没有采用这种方案;Taxonomy translation,我们已经解决了分类术语的翻译,如果你觉得我们前面的方式不够好的话,可以尝试一下这个模块;Path translation,用于翻译路经,有时候有用。

4.png 

我们这里启用了Translation setsVariable translation,前者为多个子模块所依赖,后者用于变量的翻译,很有用;Translation redirect主要用于SEO,我们这里对SEO的要求不高;User mail translation用于用户电子邮件的翻译,我们这个站点用处不大。


Drupal版本:

5.2 变量的翻译

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

首先,我们来看站点名称的翻译,我们站点的名称为“亚艾元”,在英文环境下,我们想显示拼音的形式。怎么翻译呢?导航到admin/config/system/site-information,这是站点名称所在的配置界面:

1.png 

在这个页面的上面有提示,这个表单中包含多语言的变量,我们将它切换到英文的环境下,admin/config/system/site-information?variable_realm_key_language=en,在这种情况下,输入拼音,保存:

2.png 

此时,我又遇到了一个问题,那就是虽然我这里输入了变量的英文版本,但是在首页的中英文切换的过程中,站点名称始终是中文。我尝试了比较多的办法,比如分别使用路经: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,对于界面语言的检测方法,我们与内容的保持一致。

3.png 

保存这里的配置。注释掉,我们前面所写的预处理函数。站点名称的中英文切换,正常。当然,前面的工作,也不是没有白做,如果你跟着阅读了源代码,会对Drupal7多语言的背后机制有更深的理解。比如这个语言,它分为:内容、界面、路径。我们这里对这个概念有了更深的理解。我们前面的获取当前语言,其实是获取当前内容语言,而不是获取当前界面语言。

4.png 

5.png 

如果,我们这里是一个Logo,中文Logo和英文Logo不一样,怎么解决呢?导航到zh-hans/admin/config/regional/i18n/variable

6.png 

选中这里的主题设置复选框即可,这样主题的Logo就支持多语言了,分别为每个语言上传一个Logo,解决了Logo的多语言问题。

 


Drupal版本:

5.3 菜单的翻译

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

我们来看一下如何翻译主菜单,导航到主菜单的编辑页面,admin/structure/menu/manage/main-menu/edit。这里面有一个多语言的配置选项:

 

1.png 

第一个选项,菜单项没有多语言选项,只有菜单本身可被翻译。菜单本身可被翻译?如何理解,看这个菜单右上角的标签,里面有一个“翻译”标签:

2.png 

点击这个“翻译”标签,就可以对菜单进行翻译。只是我们这里没有必要。

第二个选项,翻译和本地化。注意,这里的翻译(translate)和本地化(Localize)之间是有区别的。如果一个菜单项,它具有语言属性,此时会允许翻译;如果它没有设置语言,则可被本地化。

第三个选项,固定语言,每个菜单项都有一个语言属性,它们只会显示在自己的语言下。

我们这里选择第二个选项,保存。我们现在对主菜单的菜单项,进行编辑:

3.png 

点击“首页”菜单项右边的编辑链接。进入菜单项的编辑页面。

4.png 

此时,右上角有了一个“翻译”标签,我们点击这个标签,就可以对这个菜单项进行翻译了。

5.png 

点击操作里面的“翻译”链接,我们将菜单项的标题翻译一下:

6.png 

翻译好了保存结果。这是翻译后的样子:

7.png 

菜单项的编辑页面,还有一个语言选项:

8.png 

我们可以设置,这个菜单项是属于哪个语言下的。这样的话,我们可以为每种语言都创建一个对应的菜单项,也能解决问题。

因为,我们这里面,中文、英文的节点ID是相同的,所以我们没有必要创建多个菜单项。直接对菜单项的标题进行翻译即可。

重复前面的操作,直到把主菜单里面剩余的菜单项都翻译完毕为止。需要说明一下的是,当我们翻译到“关于我们”下面的第一个子菜单项“公司历程”的时候,菜单项编辑页面的右上角没有“翻译”标签。如果我们直接输入对应的路径的话,此时会提示没有权限。这是因为,我们还没有翻译菜单项“公司历程”所对应的节点,我们将对应的节点翻译成英文后,这里的菜单项,也可以翻译了。

到最后,只剩下“联系我们”这个webform页面了,这也是一个普通的节点。我们首先让内容类型Webform支持字段翻译,将它的Title替换成字段的形式。这个时候,我们就可以将“联系我们”这个节点的标题和正文翻译成英文了。之后,就可以翻译对应的菜单项了。只不过这个页面的表单还无法翻译,主要是表单元素的标签,在英文环境下还是显示的中文。

9.png 

我们现在先不管这个,到此,整个主菜单里面的所有菜单项,都被翻译成为了英文。注意,

10.png 

     注意,这里不仅仅是主菜单,左边的Menu block,以及面包屑都变成英文的。这说明了Menu blockMenu Position模块对多语言的支持是比较友好的。

 


Drupal版本:

5.4区块的翻译

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

不过,左下角的“联系我们”区块,仍然是中文的,我们来看一下,如何将它翻译成英文。点击它的配置链接,进入它的编辑页面en/admin/structure/block/manage/block/2/configure。在这里,可见性设置里面,多了一个语言选项。

1.png 

     这里有两种方式,第一种方式,是将这个区块标记为可翻译的,也就是选中“Make this block translatable”。选中后,下面的按钮多出来了一个:

2.png 

我们可以点击“保存并翻译”按钮。

3.png 

我们点击英文右边的翻译链接,来翻译这个区块:

4.png 

遗憾的是,我们这里面只能翻译区块标题,不能翻译区块的正文,这是因为区块正文所使用的文本格式不支持多语言。如何让它支持多语言呢?导航到i18n的管理界面,点击右上角的“字符串”标签:

5.png 

这里有两个配置选项:

6.png 

7.png 

对于源语言,我们使用默认的简体中文即可。对于可翻译的文本格式,我们这里选中所有的,保存。回到,刚才的区块的翻译页面,现在就可以翻译区块正文了:

8.png 

在这里,输入对应的英文。注意,对于区块正文,应该保留原来的HTML标签。

我们可以创建两个区块,一个显示在中文下,一个显示在英文下,两个区块显示在同一个区域的同一位置。这也是一种常见的解决方案,我以前就非常喜欢这种方式。

我发现一个问题,面包屑没有正确显示:

9.png 

具体原因不明。我把新闻、产品所有节点也都翻译了一遍,使用的Google翻译,没有人工校对。

现在,我们重复前面的操作,将“页脚菜单”、“版权信息”也翻译成英文。

10.png 

     令人遗憾的是,我们将所有的菜单项翻译后,在英文环境下,显示的还是中文。这是我的翻译:

11.png 

原因未明。我们暂时先不管它。来看“版权所有”区块,我们对它进行配置,将它只显示在中文下:

12.png 

接着,创建一个新的静态区块,是版权所有区块的英文版:

13.png 

也放在页脚区域,这里只显示在英文环境下; 

14.png 

     保存。这个区块的多语言,我们也解决了。来看页脚菜单区块,这个区块我们用的是核心自带的,我们前面讲到左边的菜单区块(menu block)的中英文显示是正常的,我们将这个页脚菜单导航替换成Menu block模块提供的方式显示。


Drupal版本:

5.5 使用Menu block输出菜单

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

导航到区块的管理界面,创建一个新的menu block(菜单区块),做以下配置:

1.png 

我们将这个区块放在页脚区域,测试一下。中英文显示正常了。把原来的核心自带的区块禁用。现在页脚也正常了。

2.png 

我们没有必要去深究,为什么核心自带的对多语言支持不友好,只要解决问题就好。有时候换种方式,绕过去,可能会更好。


Drupal版本:

5.6 Views的翻译

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

我们现在回到新闻列表页面,或者一个新闻节点页面,此时的面包屑是不正常的。我们前面已经提到过了。我想这里之所以显示“新闻”两个字,是因为Views里面的配置问题。我们编辑对应的Views,将标题设置为英文的形式:

1.png 

现在,在英文环境下,面包屑显示正常了,但是在中文环境下,又不正常了。

2.png 

可是,这个面包屑是基于菜单的,而我们的菜单项中,已经完成了“新闻”到“News”的翻译。经过测试,发现,新闻节点页面的面包屑,是基于菜单的;新闻列表页面,是基于Views的。

为了解决这个问题,我们下载、安装、启用Internationalization Views模块,我这里使用的版本是i18nviews-7.x-3.x-dev。这个模块只有开发版,不过Drupal7下的开发版的安装量也超过了1万。安装后,报了一个错:

3.png 

这样的错误消息很多,我们这里不去管它。我最终成功解决这个问题,解决办法如下:

导航到admin/config/regional/translate/translate,在过滤条件中:

4.png 

将搜索限制在视图上,也就是Views上。这个时候,会列出Views中的很多需要翻译的字符串:

5.png 

这里的“新闻”,也就是news视图的标题,我们把它翻译一下:

6.png 

翻译后,测试了一下,发现不行。我又导航到admin/config/regional/translate/i18n_string,在这里刷新了一下字符串:

7.png 

这样新闻列表的面包屑,就显示正常了。

8.png 

用同样的版本,解决产品列表的面包屑显示。需要说明的是,上面的刷新字符串在这里没有起作用,真正起作用的是清除缓存。

9.png 

不过令人遗憾的是,新闻节点页面,在英文环境下的面包屑显示不正常:

10.png 

但是产品节点的显示就正常。两者之间的配置,我记得没有任何不同。我对这个问题研究了很久,始终找不到解决办法。


Drupal版本:

5.7 使用jQuery解决无法翻译的字符串

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

我是这样解决的,解决的办法不是很地道。首先是编辑当前主题的info文件yaiyuan.info,取消注释这句代码:

scripts[] = js/script.js

接着向script.js这个文件中添加以下代码:

jQuery.noConflict();

(function($) { 

$(function() {

    

  $('.i18n-en .breadcrumb li a').each(function(index){ 

    if($(this).attr('href') == '/yaiyuan1/en/news'){

   //$(this).addClass('abc');

   $(this).html('News');

}

  });

 

});

})(jQuery);

这段JS的作用,就是将面包屑中“新闻”这个链接的文本替换为“News”。

有时候,问题实在解决不了的话,可以借助于jQuery, Hack一下,也没有关系。


Drupal版本: