2009-09-01 141 views
8

在使用查找表的多语言应用程序中,处理翻译的最佳方式是什么?在查找表中处理I18N的最佳方式是什么?

例如,对于国家查询表,美国用户应该看英文国名,因为德文应该看德文名。但他们的ID仍然应该是一样的。

我能想到以下几点:

  • 添加不同的查找表,每种语言
  • 使用标记根据其语言与同一国家的多个条目的单个查找表。
  • 由程序代码摆脱所有查找表,并尽一切查找
  • [任何其他想法,我没有想到的?]

回答

8

这里最大的问题是 - 可转换可通过改变到底用户?

如果答案是“否”,资源包比表更容易和更快使用。而不是实际的文本,你的表将包含资源键(或者如果它是文本而不是数字,你可以使用主键),并且适当的资源包将包含翻译。

如果答案是“是”,则必须将翻译存储在数据库中。然而,我发现在这种情况下最简单的方法是模拟数据库中的上述资源包功能 - 例如,有一个带有“locale”,“resource key”,“resource value”列的表,所有其他表将用来查找实际本地化文本。

3

编程中的不相交呈现。在内部,为所有事物使用ID;当向用户呈现时,呈现本地化数据。

1

我做了一次多语言应用程序。每件事都必须是多语言的,包括用户输入的内容,而且对这些内容进行翻译也很容易。

现在,如果它只是用于静态文本,最推荐资源xml文件来做到这一点。我相信这很好的支持.NET框架。

如果它是动态的,然后我做了

表ResourceStrings RESOURCEID GUID PK cultureCode字符串PK表结构 文本字符串

然后,这让我的todo级联阅读的文化代码以及。所以,如果有人的EN-US,我可以做一个查询的文化代码,我做了

SELECT FROM ResourceStrings 
WHERE resourceId = <AND ID> AND cultureCode IS IN ('en','en-us') 
ORDER BY cultureCode DESC 

这样,最长的文化代码会回来的第一和最具体的。现在,如果您允许用户输入文本并翻译它,我只会推荐这一点。我需要这个,因为内容必须是多语言的以及应用程序本身。

0

看看像Adobe Source Libraries'xstring数据结构和算法。本地化处理时使用字符串的id以及详细说明本地化的上下文。本地化表可以存储在XML中,并且字符串根据运行时上下文(语言,国家,平台等)在运行时本地化。)虽然代码本身的作品,我不会考虑它的生产质量。不过,这些概念是可靠的。

1

在我当前的项目中(一个用django编写的自定义CMS),我们针对I18N模型的解决方案基于此示例片段:http://www.djangosnippets.org/snippets/855/,我扩展为在模板中更易于使用,并且集成在管理界面中。基本上,每种类型的内容都有两个表格:一个具有公共字段(如文章的类别),另一个具有可翻译的内容(标题,正文,slu - - 用于url的独特标签等)。显然,通用模型与翻译模型之间存在着多对多的关系。这里是作者给出的例子:

class Article(models.Model): 
    author = models.CharField(max_length = 40) 

class ArticleI18N(I18NModel): 
    title = models.CharField(max_length = 120) 
    body = models.TextField() 

我认为这样,数据库布局真的接近于具有共同属性和可转换字段的内容的概念。

但是,棘手的部分是在你的代码中保持DRY,否则每当你需要处理可翻译的内容时,最终会产生一堆样板。幸运的是,python的灵活性非常有帮助。

如果你的编程语言和环境不允许类似的技巧(比如动态创建子类,python的metaclasses--某种继承钩子等等),我想这种数据库布局将比诅咒更多祝福。

因此,请牢记YAGNI原则。如果你需要你的模型中的翻译,并发症少,我见过的其他有效的方法,这是罚款,只要你能承受的灵活性有限,以及缺乏这些替代品的概念完整性的:

  • 1)使用每个可翻译列和每种语言的附加列:title_en,title_fr,title_de,content_en,content_fr,content_de,...
  • 2)在一列中串行化多种语言。
    例如:title =“| EN |欢迎| FR | Bienvenue | DE | Willkommen”
    我不太喜欢那个,但真正重要的是它是否很好地整合到现有环境中,情况就是如此。
  • 3)有时,不同语言中相同内容之间的链接不需要严格。我认为这是维基百科文章的情况 - 翻译只是作者手动设置的超链接。因此,这些链接很少被软件利用,但这里重要的是用户可以浏览。
1

以下是在数据库级别执行此操作的一种方法。

当我需要这样做时,我将每个代码表分成两个表格。一个包含文化不变数据:代码的内部ID肯定,代码本身(如果代码是文化不变的),可能还有其他列(如排序/分组类别)。另一个包含文化特定数据:描述,文化特定代码(如果适用)等。

(特定于文化的代码是一个马蜂窝;如果你不需要,它不会踢它,你可能有点难以理解USEU是不同的代码但是在有些国家,法语国家的用户使用US作为他们的缩写États-Unis,这在政治上可能会让人难以接受。那么,a国家。)

让文化不变的代码表允许你在它和使用它的主表之间建立外键约束。构建区域性特定的查询是非常简单的:

SELECT m.*, c.Code, ISNULL(s.Description, lf.Message) 
FROM MainTable m 
JOIN FooCodeData c ON m.CodeID = c.ID 
LEFT JOIN CultureSpecificFooCodeData s ON s.CodeID = c.ID AND s.Culture = @Culture 
JOIN LookupFailure lf ON lf.Culture = @Culture 

需要注意的是,如果你的代码是文化特有的,你甚至都不需要加入FooCodeData在该查询,选择s.Code代替。

还要注意这种方法的一个固有弱点,如该查询中的LEFT JOINISNULL所示:您无法创建约束条件来保证每个代码/文化组合都存在特定于文化的行。这就是LookupFailure的用途:它获取特定于文化的消息,指示特定文化代码记录尚未输入给定代码。

相关问题