获取文本:消息 ID 是英文文本是个好主意吗?


Gettext: Is it a good idea for the message ID to be the english text?

我们正准备将我们的PHP网站翻译成各种语言,PHP中的gettext支持似乎是要走的路。

我看到的所有教程都建议使用英文文本作为消息 ID,即

获取文本("你好!

但这真的是个好主意吗? 假设营销部门有人想将文本更改为"您好,你们! 那么,您是否不必更新所有语言文件,因为该字符串(实际上是消息 ID)已更改?

拥有某种通用 ID(如"hello.message")和英文翻译文件是否更好?

哇,我很惊讶没有人提倡使用英语作为密钥。 我在几个软件项目中使用了这种风格,恕我直言,效果很好。 代码的可读性非常好,如果你改变一个英文字符串,很明显,消息需要考虑重新翻译(这是一件好事)。

如果您只是更正拼写或进行一些绝对不需要翻译的其他更改,则在资源文件中更新该字符串的 ID 很简单。

也就是说,我目前正在评估是否将这种I18N的方式推进到一个新项目中,所以很高兴听到一些关于为什么它可能不是一个好主意的想法。

我强烈不同意理查德·哈里森的回答,他说这是"唯一的方法"。亲爱的提问者,不要相信一个说这是唯一方法的答案,因为"唯一方法"并不存在。

这是恕我直言的另一种方式,与理查兹的方法相比有一些优势:

  • 首先使用英语字符串的原型版本作为原始字符串。
  • 不要显示这些原型字符串,而是为英语创建一个翻译文件
  • 将原型字符串复制到开头的翻译中

优势:

  • 可读代码
  • 代码中的文本与视图显示的文本非常接近(如果不是相同)
  • 如果要更改英文文本,则无需更改原始字符串,而是更改翻译
  • 如果你想翻译同样的东西两次,只需写一个稍微不同的原型字符串,或者只是添加"这个和那个的版本",你仍然有一个完全可读的代码

我使用有意义的ID,例如" welcome_back_1",这将是" welcome back, %1 "等。我总是将英语作为我的"基本"语言,因此在最坏的情况下,当特定语言没有消息 ID 时,我会回退到英语。

我不喜欢使用实际的英语短语作为消息 ID,因为如果英语发生变化,ID 也会发生变化。如果您使用一些自动化工具,这可能不会对您产生太大影响,但这让我感到困扰。我不喜欢使用简单的代码(如msg3975),因为它们没有任何意义,所以阅读代码会更加困难,除非你到处乱扔评论。

ID

为英语的原因是,如果翻译因任何原因失败 - 当前语言和令牌的翻译不可用或其他错误,则返回 ID。当然,这是假设开发人员正在编写原始英文文本,而不是某个文档人员。

另外,如果英文文本发生变化,那么其他翻译可能需要更新?

在实践中,我们也使用纯ID而不是英文文本,但这确实意味着我们必须做很多额外的工作才能默认为英文。

有很多事情需要考虑,回答并不容易。

使用简单的英语

优点

  • 易于编写和读取代码
  • 在大多数情况下,即使没有在代码中运行翻译函数,它也可以工作。

缺点

  • 参与其中的程序员也必须是优秀的撰稿人:)
  • 你需要
  • 完全用英语写出正确的精确文本,即使你需要运行的第一语言是其他语言(即我们正在用捷克语启动项目,稍后我们会将它们本地化为EN)。
  • 在很多情况下,您需要使用上下文。如果你没有从乞丐那里做到这一点,以后添加它们需要做很多工作。解释一下:在英语中,一个单词可以有许多不同的meands-您需要使用上下文来区分它们-并且并不总是那么容易(order =排序顺序,也可以是采购订单)。
  • 这个过程的后期纠正英语可能非常困难。源字符串的更正通常会导致已翻译短语的丢失。仅仅因为您纠正了英语就将翻译松散到 3 种不同的语言是非常令人沮丧的。

使用密钥

优点

  • 您甚至可以使用本地化平台功能,甚至可以使用英语。 也就是说,我们正在使用可爱的Crowdin平台。有很多方便的工具 - 或者更确切地说是一个完整的工作流程 - 用于翻译管理:为不同的翻译投票,翻译历史,词汇表(有助于保持翻译/语言的连贯性),校对,批准等。使用密钥使此过程更加顺畅。

  • 发送英语文本进行校对等要容易得多。 通常,让撰稿人直接修改您的代码不是一个好主意:)

缺点

  • 更复杂的项目设置。
  • 更难使用 %d、%s 等。
总之,

不要这样做。

英语中的同一个单词/短语通常具有多个含义,并且每个含义都有不同的翻译。

为字符串定义助记符 ID,并将英语视为另一种语言。

同意其他海报的观点,即代码中的 ID 号是代码可读性的噩梦。

前本地化工程师

你不是已经回答了你自己的问题吗? :)

显然,如果您打算支持应用程序的 i18n,则应对所有语言实现一视同仁。 如果有人决定需要更改字符串,则在所有语言文件中进行类似的更改。 签入的元数据应在同一更改中将所有语言文件组合在一起。 如果您的"默认"语言以不同的方式处理,则更难维护。

归根结底,翻译人员应该能够坐下来更改每种语言的文本(以便它们在含义上匹配),而不必让已经完成工作的程序员参与进来。

这让我觉得正确的答案是使用修改后的gettext版本,在其中放置这样的字符串

_(id, backup_text, context)
_('ABOUT_ME', 'About Me', 'HOMEPAGE')

上下文是可选的

为什么这样?因为您需要使用唯一 ID 而不是可能在其他地方重复的英文文本来识别系统中的文本。

您还应该将备份、ID 和上下文保留在代码中的同一位置,以减少差异。

id还必须是可读的,这带来了同义词和重复使用的问题(即使是id),我们可以像"HOMEPAGE_ABOUT_ME"或"MAIL_LETTER"这样的ID前缀,但是

  1. 人们一开始就忘记这样做,以后改变它是一个问题
  2. 它更灵活,系统能够按ID和上下文进行分组

这就是为什么我还在最后添加了上下文变量

备份文本几乎可以是任何东西,甚至可以是"[ABOUT_ME@HOMEPAGE文本加载失败,请联系 example@example.com]"

它不适用于当前的 gettext 编辑程序,如"poedit",但我认为您可以为翻译定义自定义变量名称,例如"t()",开头没有下划线。

我知道gettext也支持上下文,但它没有很好的文档记录或广泛使用。

附言我不确定执行良好且可扩展代码的最佳变量顺序,因此欢迎提出建议。

我什至会说你永远(对于大多数从不值)想要使用自由文本作为任何东西的键。想象一下,例如,如果 SO 使用查询标题作为此页面的键。如果有人链接到它,然后编辑了标题,则该链接不再有效。

您的问题类似,除了您还将负责更新所有链接...

就像Douglas Leeder提到的,你可能想做的是使用英语作为默认(备份)语言,尽管使用英语和另一种语言混合的界面非常令人困惑(但也有点有趣)。

除了上述注意事项外,在许多情况下,您希望"密钥"(msgid)与源文本(英语)不同。例如,在 HTML 视图中,我可能想说 [yyyy],其中该锚标记的目标和标签取决于用户的区域设置。例如,它可能是社交网络的链接,在美国是Facebook,但在中国可能是微博。因此,MsgIds可能是类似于socialSiteUrl和socialSiteLabel的东西。

我使用混合。

对于我认为不会有冲突/变化/奇怪含义的基本字符串,我会使键与英语相同。

我们使用荷兰语。字符串应以作者的母语编写;这使得与翻译人员的沟通不易出错,因为作者可以用他们的母语与他们交流。