如何处理带有标记的文本翻译?

39

我正在为我们的Web应用程序开发多语言支持。我们正在使用Django的帮助程序,围绕gettext库进行操作。除了如何处理包含重要HTML标记的句子这个问题以外,一切都出奇地容易。以下是一个简单的例子:

Please <a href="/login/">log in</a> to continue.

以下是我能想到的方法:

  1. 将链接更改为包含整个句子。无论在这种情况下是否改变是个好主意,这种解决方案的问题在于UI变得依赖i18n的需求,而两者理应是独立的。

  2. 将上述整个字符串标记为翻译(包括格式)。随后,翻译字符串将直接包含HTML。这种方法的问题在于更改HTML格式需要更改所有翻译内容。

  3. 紧密耦合多个翻译,然后使用字符串插值组合它们。例如,“请%s继续”和“登录”这个短语可以分别标记翻译,然后组合在一起。“登录”被本地化,然后用HREF包装,最后插入到已翻译的短语中,从而保留了翻译中的%s,以标记链接的位置。这种方法会使代码复杂化,并且会破坏翻译字符串的独立性。

还有其他选项吗?其他人是如何解决这个问题的?

6个回答

19

你需要的是解决方案2。将整个句子与HTML标记嵌入发送给他们。

原因:

  1. 主流翻译工具Trados可以保留标记,避免翻译人员意外破坏标记。
  2. Trados可以自动翻译之前已见过的文本,即使标记内容发生了改变(但标记数量和在句子中的位置相同)。至少,翻译人员会给你一个很好的折扣。
  3. 样式与地区相关。在某些情况下,在中文或日语中使用加粗可能不合适,斜体也较少用于东亚语言。翻译人员应该可以自由选择保留还是删除样式。
  4. 单词顺序是语言特定的。如果你将上述句子分成片段,它可能适用于英语和法语,但在中文或日语中当你串联时,单词顺序将不正确。因此,最好的国际化(i18n)做法是外部化整个句子,而不是句子片段。

12

2,可能会有变化。

您当然可以将整个字符串本地化,例如:

loginLink=Please <a href="/login">log in</a> to continue

然而,根据您使用的工具和本地化团队的要求,他们可能更喜欢您采取以下做法:

// tokens in this string add html links
loginLink=Please {0}log in{1} to continue

那将是我首选的方法。如果您有忽略某些字符的本地化工具,则可以使用不同的替换模式。例如:

loginLink=Please %startlink%log in%endlink% to continue

然后在您所使用的JSP、Servlet或等效语言中执行替换...


使用gettext,可能会是“请%s登录%s以继续”。 - hangy
1
我喜欢这个想法。我曾经考虑过将内部文本与外部文本分开作为单独的字符串,但我没有想到改变HTML本身成为插值字符串。这似乎可能效果更好,并且对于翻译者来说更不容易混淆。 - Ryan Lundy

7

免责声明:我本人在软件国际化方面缺乏经验。

  1. 我认为这样做不好,因为它会引入过多的耦合……
  2. 只要您在需要翻译的部分保持格式简洁,这种方法可能还可以。给翻译者提供特殊词汇的重要性(通过链接或使用 <strong /> 强调)似乎是一个好主意。但是,那些包含(X)HTML 的翻译可能不能轻松地在其他地方使用。
  3. 我觉得这听起来是不必要的工作……

如果是我,我会选择第二种方法,但我会将URI放入格式参数中,这样可以在不必更改所有这些翻译的情况下进行更改。

Please <a href="%s">log in</a> to continue.

请记住,如果您采用这种方法,您可能需要教授翻译人员基本的(X)HTML知识,以免他们破坏您的标记,并且让他们知道他们所写的文本的预期。无论如何,这种额外的知识可能会导致更好的语义标记,因为如上所述,文本可以被翻译并用(X)HTML进行注释,以反映当地的书写风格。


按照WordPress.org的建议,使用sprintf(__('将%1$s替换为%2$s'))。此示例适用于多个单独的HTML字符串。 - Ryan Bayne

3

无论你做什么,都要把整个句子作为一个字符串。要正确翻译,你需要理解整个句子。

并非所有语言都需要翻译所有单词:例如,在挪威语中,我们不使用“请”(我们可以说“vær så snill”,字面意思是“请这样做”,但在用作命令时,这听起来过于强制),因此正确的挪威语应该是:

  • "Logg inn for å fortsette" 字面意思是:“登录以继续”或
  • "Fortsett ved å logge inn" 字面意思是:“通过登录继续”等。

你必须允许完全改变顺序,例如在虚构的演示语言中:

  • "Für kontinuer Loggen bitte ins" (如果是真实的)字面意思是:“请登录以继续”

有些语言甚至可能有一个单词来表示(大部分)这个句子...

我会建议方案1,或者可能是“请%{startlink}登录%{endlink}以继续”,这样翻译人员可以将整个句子作为链接,如果更自然的话,也可以完全重组它。


1
有趣的问题,我很快就会遇到这个问题。我想我会选择2,没有任何棘手的东西。HTML标记很简单,URL不会很快改变,如果有任何更改,将在django.po中创建一个新条目,因此我们有机会检查翻译(例如,脚本应在makemessages之后检查空翻译)。
所以,在模板中:
{% load i18n %}
{% trans 'hello <a href="/">world</a>' %}

然后,在执行python manage.py makemessages命令之后,我会在我的django.po文件中看到以下内容

#: templates/out.html:3
msgid "hello <a href=\"/\">world</a>"
msgstr ""

我根据我的需求进行了修改

#: templates/out.html:3
msgid "hello <a href=\"/\">world</a>"
msgstr "bonjour <a href=\"/\">monde</a>"

...在我遇到的简单而频繁的情况下,这不值得再费力。这里的其他解决方案似乎很聪明,但我认为解决标记问题的方法不是更多的标记。此外,我想避免在模板中使用太多令人困惑的东西。

你的模板应该在一段时间后相当稳定,但我不知道你期望遇到什么其他麻烦。如果内容一次又一次地更改,也许该内容的位置不在模板内,而是在模型内。

编辑:我刚在文档中查看了一下,如果您需要在翻译中使用变量,则可以使用blocktrans


0
  1. 没有意义,你怎么翻译“log in”?
  2. 我认为很少有翻译者有HTML经验(普通的非HTML-aware翻译者会更便宜)。
  3. 我会选择选项3,或者使用“请%s登录%s以继续”,并用链接的一部分替换%s。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接