跳转到主要内容
rli 提交于 26 July 2012

原文链接:http://drupal.org/node/304047

在Drupal6中,核心的内容翻译模块是内容的多语言化变得可行。

它的特点包括:

  • 能够为每条内容指派特定语言
  • 是内容可以被翻译
  • 使需要更新的内容的翻译能过被标记

手册链接:http://drupal.org/handbook/modules/translation

与多语言内容工作的主要方法

下面是当我们与多语言内容工作时,一些有用的主要方法:

数据结构与概念

在数据的层面,内容的翻译被引进到node表格的三个新字段:

  • language:这个节点在language表格里的语言。
  • tnid:这个节点的翻译id,它与该节点的节点id是相同的。
  • translate:一个布林值,它来告诉我们本节点的翻译是否需要更新。

互为翻译的节点被视为一个翻译组,他们用一个共同的$node->tid来区分。一个翻译组需要有一个源节点--所有其他翻译节点的第一个版本。源节点的nid和该翻译组的tid是相同的。

如果源节点被删除了,那么另一个翻译的版本将被指定位源节点。不被标记成需要更新的翻译优先被选择为源节点。

为翻译而准备您的内容

当一条内容正在被翻译时,hook_nodeapi()将在‘准备翻译’的过程中被调用,这样可以允许其他模块来设置节点的属性,然后再把节点编辑页面显示给用户。

在把节点对象传给nodeapi的方法中,最初版本的节点将被包含在$node->translation_source对象里。所以,‘准备翻译’nodeapi将测试$node->translation_source对象并根据结果来设定节点的属性。

比如说您有个模块添加了一个叫做‘place’的字段给节点,那么hook_nodeapi()的内容至少应该是如下:

<?php function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) { switch ($op) { case 'insert': ... case 'update': ... case 'delete': ... case 'load': ... case 'prepare translation': $node->place = $node->translation_source->place; break; } } ?>

集成不同翻译版本的内容

当涉及到在不同版本的翻译之间处理节点信息的时候,模块开发的一些问题将会显现。

比如说您有一系列的多语言的内容节点,每个节点都根据不同语言有不同的版本。在默认情况下,所有节点都将是独立的。比如,用户的投票根据不同语言将会被独立的清点,这样我们如何能统计出总共的得票结果呢?

解决此类问题的方法会涉及到一些分析方法,我们可以选择:

  • 改变数据储存方式。有些时候,您需要为一个翻译组里的所有节点更新数据无论哪个用户在任何时间更新了其中一个节点。比如说,无论何时一个投票发生,系统将会在翻译组内的所有版本的节点上加一。或者也可以在源节点上加一,这样源节点就记录了不同语言节点上投票的总和。
  • 改变数据的表达方式。有时候,源数据是需要被保存的,我们需要的是改变数据的显示形式。比如说,用户在不同语言节点上注册投票,但是当每个语言节点被浏览时,我们显示的是所有语言节点上投票的总和,而不是单语言节点的票数。
  • 为整个翻译组提供一个新的集成选择。除了改变数据的显示方式,我们还可以为翻译组提供一个新的集成方法。比如,为整个翻译组提供一个视图字段,来取代单独的显示各个翻译节点。

把tid视为主要的识别变量

有时候相比于把nid作为主要节点的识别变量,对tid的应用将会更加有帮助。

任何方法如果采取了这个策略,将需要对tnid的改变作出回应。

当一个翻译组的节点被删除时,以下两件事中的一件有可能会发生:

  • 如果只剩下一个翻译节点剩下了,那么它的tid将会变成0.
  • 如果被删除的是源节点,那么新的源节点将被选出,其他的翻译节点将根据这个变化作出改变。

任何依赖tid的方法,将需要对这个动作作出反映。一般来说,我们需要做的是:

  • 如果tid被转化成0了,那么就用nid来作为主要识别变量。
  • 如果源节点被改变了,用老的tid来更新数据。