【问题标题】:Gettext tool to use the translation in one language as the key for translation in another languageGettext 工具使用一种语言的翻译作为另一种语言的翻译键
【发布时间】:2014-06-19 08:44:08
【问题描述】:

是否有工具可以执行我在问题标题中提出的建议?考虑以下场景,其中msgid"%s minutes left",英语中的msgstr 是一样的,而另一种语言中的msgstr"bla %s bla"。营销人员决定在英语中字符串应该是"%s minutes left, hurry up!"。我该怎么办?一方面,我可以更改msgid。从好的方面来说,很明显语言的翻译需要更新;但是字符串更改需要开发人员更新源文件,这听起来不像是很好地利用了开发人员的时间,因为要实现的功能太多且时间稀缺。另一方面,翻译人员可以更新英文的 msgstr,以符合营销人员的要求,但是我如何通知翻译人员他们必须更新他们的翻译?此外,他们看到的只是msgid,它没有改变。那么如何告诉他们实际的字符串是什么?

感谢任何可以提供帮助的人。

【问题讨论】:

  • 对于使翻译更容易的工具,您可以查看poedit(因为您没有提到它),但我认为它无法处理“您需要更改原始文本后的翻译”改变了'。

标签: php localization internationalization gettext


【解决方案1】:

这是一种常见的情况,无论好坏,几乎都内置在 Gettext 的预期工作流程中。

正常的工作流程是:

source code > extract to POT > generate PO > translate PO

对源文本的修改是:

edit source > extract new POT > merge into PO > review fuzzy strings

msgmerge 命令行工具允许您将修改后的 POT 文件与已翻译的 PO 文件合并。这会将源语言已更改的所有翻译标记为模糊,这意味着翻译人员可能需要再次检查他们的翻译是否仍然准确。

msgmerge old.po changes.pot -o new.po

POEdit 程序还通过“从 POT 更新”菜单选项具有此功能,我怀疑它可能在后台使用 msgmerge 程序。

正如@deceze 所指出的,使用“机器 ID”将源字符串与翻译分开,可以避免此类问题。尽管这是许多其他本地化平台的工作方式,但 Gettext 并不是真正的工作方式(方钉、圆孔等)

或许值得一提的是,您可以使用“Extracted cmets”功能向翻译人员传达更多信息。在 PO/POT 文件中,它们用“#.”前缀表示。 xgettext 程序从您的源代码中提取这些,但您也可以手动维护它们。

例如,如果您想维护一个英文 PO 文件(供您的营销人员编辑)并在您的代码中使用机器 ID,您可以这样:

#. %s minutes left
msgid "time-nag-minutes-left"
msgstr "%s minutes left, hurry up!"

其中第 1 行是您的原始源代码注释,显示初始英文,第二行是您的机器 ID,第三行是您的营销人员编辑“翻译”,无需再次编辑源代码。

我不建议这样做 - 它是非标准的,您的翻译人员可能习惯于 Gettext 以应有的方式工作。不过,这是一种选择。

【讨论】:

    【解决方案2】:

    使用 gettext,您有两种选择:

    1. 在源代码中使用“字符串 id”并在 PO 文件中提供所有 UI 文本。例如:

      msgid "FRONTPAGE_SALES_CALL_TO_ACTION"
      msgstr "Buy now, buy often!"
      

      这样做的好处是你可以纯粹通过编辑 PO 文件来更改 UI 文本,而不需要触摸代码。它的缺点是您的用户会在 UI 中看到缺少翻译的废话,并且 UI 代码更抽象/无意义,可能会使正确使用/原型制作变得有些困难等。它还引入了与翻译工作的复杂性,正如你提到的那样。

    2. 在您的代码中使用文字 UI 文本,并且只在 PO 文件中为其提供翻译。

      在这种情况下,您应该拥有源语言的 PO 文件,其中每个 msgidmsgstr 都是相同的。这只是多余的。

      如果您正在使用这种风格(显然您是),那么任何实际的文本更改都必须在源头发生。源代码是您的规范 UI;如果您要更改消息的含义,这实际上是 UI 的更改,因此需要更新 UI 代码。然后,您使用xgettext(或类似工具)将该更改与您的 PO 文件同步,这会将更改传播到所有翻译文件并标记更改的字符串以进行翻译(或者甚至提取现有的翻译,如果可用)。

    你不应该养成做 2 的习惯。而是像对待 1 一样对待它。这会导致很多混乱的WTF?!时刻。

    如果您想让“前端人员”无需接触复杂的源代码即可更改文本,您需要将前端代码与后端代码更好地分离。这不一定是 gettext 的任务,而是更好的模板系统或更好的 MVC 分离。

    【讨论】:

    • 感谢您也让我的声明更清晰。我认为您对解耦特别正确,但是我认为无论如何,想要更改文本的人都需要在某处编辑模板文件,如果他们甚至不想编辑该文件,则开发人员必须这样做;你同意吗?
    • 无论如何你的回答也让我看到我的问题标题与问题主体关系不大,我的错。我认为我坚持使用 (1) 或 (2),但是在任何情况下,使用除 msgid 之外的其他工具作为源语言都会非常有用。
    • 实际上,我想修正我的第 1 点:你永远不应该这样做,这不是 PO 文件的用途。因为如果你这样做,你将不得不单独向翻译人员传达“FRONTPAGE_SALES_CALL_TO_ACTION”应该说的内容。翻译者无法根据自身的优点翻译此信息。它破坏了整个 gettext 工作流程。 (基本上是你自己提到的问题的大局。)另外,改变一个句子可能会产生超出单个句子的影响。也许您必须重排 UI,使按钮变大等。任何 UI 更改都需要 UI 专家来完成。
    • ... 如果让非开发人员更改 UI 是贵公司的优先事项(取决于使用案例,这是一件非常合理的事情),你应该在你的允许人们这样做的系统。例如。您的 UI 中有那些“FRONTPAGE_SALES_CALL_TO_ACTION”标记,然后将其提取为非开发人员易于使用的格式,然后通过 gettext 工作流程进行处理。或者有一个专门为此而设计的所见即所得 CMS 系统。但不要使用 gettext 作为中间层。
    • 是的,如果可能的话,我不会让非开发人员在 UI 上工作,但事实上,我正在做的是在 gettext 之上添加一个层以使非开发人员能够做出改变,因为这是公司现在需要的。我想我正在寻找的那种功能是我将在这个外层提供的东西......
    最近更新 更多