将多语言功能引入CiviCRM时,一件事情是弄清楚(并且实际上在之后实现…)存储和管理多语言数据的整个机制,但另一件完全不同的事情是选择哪些数据库字段/列应该从(或者被诅咒具有)存在于并行、依赖语言的版本的能力。
CiviCRM中管理多语言数据的基础是基于将某些单语言数据库列替换为其多个副本(每种语言一个)的想法。例如,一个俄语+英语网站可能希望同时以西里尔字母和英文转写存储联系人名称;为了实现这一点,当网站变为多语言时,civicrm_contact表的last_name列被替换为last_name_en_US和last_name_ru_RU列。
为了使这种方法从编码角度可用,列替换的同时创建了新的视图(每个表+语言组合一个)。这些视图在它们的“原始”名称下公开特定的语言列;例如,在上面的例子中会创建两个视图:civicrm_contact_en_US(它将last_name_en_US作为last_name公开)和civicrm_contact_ru_RU(它将last_name_ru_RU作为last_name公开)。这个解决方案意味着所有现有的数据库查询都可以通过简单地给表名加上当前区域设置后缀来即时重写,因此发出查询的代码甚至不需要知道它正在与一个多语言数据库工作。
如引言所述,上述方法的实现仅仅是“如何存储多语言CiviCRM数据”问题的部分(即使是主要部分)。另一个问题是哪些字段(数据库列)应该得到这种特殊处理。一方面,在某些特殊情况下,能够以不同的语言展示大量CiviCRM数据可能是有用的;另一方面,大多数安装并不真正需要在不同语言版本中有关于动物收容所容纳10只狗和20只狗的记录(因此,显然,数值型自定义数据不应支持多语言——但是如果有关于“我们可以收容的物种”的自由文本字段呢?)
我解决这个问题的通用方法是基于回答以下问题:潜在字段是否为自由文本字段(这是考虑字段是否支持多语言的前提);它关乎用户界面而不是实际数据(即,表单前后帮助文本,在 不同语言中应该确实是不同的);它是否存储了一些应该在不同语言中保持同步且不随语言变化的数据(因此,使字段支持多语言将是一个坏主意),如电子邮件地址;它是否从支持多语言中受益,如关于联系人的笔记内容——一方面,给定CiviCRM安装的用户可能是多语言的,并从翻译后的笔记中受益,但另一方面,在大多数情况下,管理联系的人员使用一种通用语言,并且笔记内容的潜在差异将是有害的;最后,一些肯定是硬数据且应该在所有语言中保持不变的部分实际上是否受益于可转写性,如能够以西里尔字母写下联系人姓名(或地址),如上例所示。
在CiviCRM团队内部进行了一些讨论后,我们决定首先将核心字段的一小部分设置为支持多语言,然后根据我们的调用是否正确以及多语言社区的反馈(“如果X字段支持多语言,将真正帮助我们”)来扩展范围;因此,我最近对CiviCRM的更改,增加了支持多语言字段的数量。
关于这些字段的最后一个问题是,如何在用户界面中展示它们的多语言功能。一个明显的解决方案是在切换到给定语言时编辑内容的正确版本(这正是CiviCRM所做的);另一个解决方案是引入小型的弹出窗口,允许跨所有支持的语言即时访问(和编辑)给定字段的值。我很高兴地说,这个功能最初只是作为概念验证解决方案为少数几个字段实现,已经成功地从Dojo迁移到jQuery,变得更加有用,因此,扩展到覆盖几乎所有的多语言字段。
现在,我开始让多语言升级路径在代码级别上更容易应对——带着我的CiviCRM 3.0发布经理的帽子,我本周确实有兴趣让它尽可能简单。:)