【问题标题】:How can I reuse i18n translation keys in Angular?如何在 Angular 中重用 i18n 翻译键?
【发布时间】:2018-01-25 03:37:33
【问题描述】:

我正在使用 i18n 对 Angular2 (4.0.3) 的支持,如 here 所述。我已经生成了xlf 文件,一切正常。

但是,假设我有一个链接到我的主页的菜单按钮。我使用属性i18n="@@homeTitle" 创建了DOM 节点。现在,在我的主页组件中,我想在<h1> 标记中使用相同的翻译ID,这样我就可以得到相同的翻译,而不必维护多个具有相同内容的条目xlf 文件。

我曾希望做类似下面的事情,并让它使用适当的翻译自动填充我的<a> 节点。

// home.component.html
<h1 i18n="@@homeTitle">Home</h1>

// menu.component.html
<a routerLink="/" i18n="@@homeTitle"></a>

但是,这不起作用。 &lt;a&gt; 节点显示为空文本,而不是翻译目标。 (此外,默认情况下,自动生成的messages.xlf 文件中没有翻译目标。)

文档实际上是call out this situation,但没有提供解决方案。用户on GitHub 也针对 Mondaycancel 等常见字符串提出了该问题,但该问题线程并未涵盖此特定问题的解决方案。

如何跨多个节点重复使用我的xlf 文件中定义的 i18n 翻译?

编辑:这里是使用ng-xi18n --i18nFormat=xlf生成的xlf

<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
  <file source-language="en" datatype="plaintext" original="ng2.template">
    <body>
      <trans-unit id="homeTitle" datatype="html">
        <source>Home</source>
        <target/>
      </trans-unit>
    </body>
  </file>
</xliff>

如果切换两个@@homeTitle节点的解析顺序,&lt;source&gt;会分别改变。

【问题讨论】:

  • 你能不能显示相关的 xlf ?另外你用什么来提取翻译键并生成 xlf ?
  • @Romain 我已经添加了xlf,虽然我不确定它会有多大用处。

标签: angular internationalization


【解决方案1】:

TLDR;只是不要担心自定义 ID 并正确编写您的字符串。 ng xi18n 工具将负责匹配单个 &lt;trans-unit&gt; 下的相同字符串。然后您的翻译将应用于整个单元。

更长的解释:xi18n 工具通过字符串相等来匹配您应用中的字符串。每当它找到一个新字符串时,它都会将它与已经找到的字符串进行比较。如果存在完全匹配,则它将新字符串包含在现有&lt;trans-unit&gt; 中。如果没有,它会创建一个新的并生成一个新的 ID。

但是,可以通过使用自定义 ID 和翻译提示来更改此行为。如果找到新字符串并包含自定义 ID,则将检查当前消息是否有此特定 ID,并分配给现有的 &lt;trans-group&gt;(如果找到)。请注意,此过程忽略字符串本身,因此任何 非空 值都将合并到具有自定义 ID 的找到的 &lt;trans-group&gt; 中。空字符串被省略。

正如文档所述,只有具有自定义 ID 的第一个元素会被检查是否有 source 字符串。当存在具有相同 ID 的第二个元素时,它的字符串值将不会被解析。这意味着您可以更改您的解决方案以使具有您的自定义 ID 的所有其他节点都包含占位符字符串。然后本地化将按您的预期工作。

// home.component.html
<h1 i18n="@@homeTitle">Home</h1>
// menu.component.html
<a routerLink="/" i18n="@@homeTitle">ANY PLACEHOLDER STRING YOU WANT</a>

如您所见,这看起来并不特别花哨。此外,您必须记住自定义 ID 以便进一步重复使用。我建议不要这样做,除非绝对必要。在我看来,只需编写字符串(在您的情况下为"Home"),将i18n 属性添加到元素上并不必担心重复使用,因为它会自动完成,因此更容易。我会使用自定义 ID,主要是在您需要对一个字符串进行多个不同(上下文)翻译的情况下。

【讨论】:

  • 感谢您的建议。我担心只使用独立的i18n 属性:假设我在十个地方使用了一些字符串(可能是模态上的术语Cancel)。然后我决定要在所有位置更改该词(例如,将所有 Cancel 更改为 No)。我现在必须找到所有十个字符串并将它们全部替换。如果他们都在一个 ID 下,我只需要进行一项更改。至于您的ID匹配想法,我明确提到这不起作用。使用默认语言环境时,会出现ANY PLACEHOLDER STRING YOU WANT
  • 嗯,是的。那么一个好的做法是让默认字符串不是语言环境本身,而是所有语言环境的模板。即使您的默认语言是英语,您仍然会生成messages.xlf,但随后会从这些语言中创建messages.en.xlf(提供其中的翻译——它们中的大多数将是相同的字符串)。查看this tutorial 了解如何轻松做到这一点。
  • 我想我很失望,这是最好的解决方案。当应该内置这种功能时,必须维护默认语言的翻译文件似乎有点愚蠢。嗯,也许它会在未来的 Angular 版本中得到解决。
猜你喜欢
  • 1970-01-01
  • 2014-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-11
相关资源
最近更新 更多