i18next翻译中的HTML标签

39 javascript internationalization i18next

我正在使用i18next为我的博客提供i18n电源.它在纯文本内容上运行良好,但是当我尝试翻译包含HTML标记的内容时,它在翻译文本时显示原始标记.

举个例子,这里是一个帖子的标记片段,它没有按预期工作:

<div class="i18n" data-i18n="content.body">
  In Medellín they have many different types of <i>jugos naturales</i>&nbsp;(fruit juice) ... <br />
  <br />
  ...
</div>
Run Code Online (Sandbox Code Playgroud)

翻译代码如下所示:

var resources = {
  "en": ...,
  "es": {
    "translation": {
      "content": {
        "body": "En Medellín hay varios tipos diferentes de <i>jugos naturales</i> ... <br /><br /> ... "
      }
    }
  }
}

i18n.init({"resStore": resources}, function( t ) {
  $('.i18n').i18n();
});
Run Code Online (Sandbox Code Playgroud)

呈现翻译时,HTML标记将被转义并作为文本输出:

En Medellín hay varios tipos diferentes de &lt;i&gt;jugos naturales&lt;/i&gt;...&lt;br /&gt;&lt;br /&gt;
Run Code Online (Sandbox Code Playgroud)

如何让i18next更改已翻译元素的HTML?

小智 41

为了使这项工作,您必须为data-i18n要翻译的元素的属性添加前缀[html]:

<div class="i18n" data-i18n="[html]content.body">
Run Code Online (Sandbox Code Playgroud)

资料来源: i18next.jquery.js


小智 15

你需要关闭转义:

i18n.t("key", { 'interpolation': {'escapeValue': false} })

  • 对于试图在反应中使用react-i18-next进行此操作的任何人**,请注意React也会逃脱字符串!要告诉React不要转义字符串,我们必须使用React的丑陋[dangerouslySetInnerHTML](https://github.com/i18next/react-i18next/issues/189#issuecomment-234870445)技术:`<div dangerouslySetInnerHTML = {{__ html :t('foo')}} />` (13认同)

小智 14

这是 React 的答案。

最终找到了一个简单的解决方案,可以使代码更易于维护。希望这可以帮助!

{
  "stackoverflow": "<site_anchor>Welcome to stackoverflow!</site_anchor> You can also <profile_anchor>check my profile</profile_anchor>" 
}
Run Code Online (Sandbox Code Playgroud)
import {Trans} from "react-i18next";
Run Code Online (Sandbox Code Playgroud)
<Trans i18nKey="stackoverflow" components={{
  site_anchor: <Link href="https://stackoverflow.com" target="_blank"/>,
  profile_anchor: <Link href="/sf/users/1269180251/" target="_blank"/>,
}} />
Run Code Online (Sandbox Code Playgroud)


erm*_*off 12

不要将 HTML 标签放入翻译中。无论如何,这是一个坏主意。关注点分离的人都会对此抱怨不已。

<Trans>如果react-i18next [https://react.i18next.com/latest/trans-component][1],请使用该组件

这样做:

// Component.js

<Trans>Welcome, <strong>User!</strong>, here's your <strong>broom</strong></Trans>
Run Code Online (Sandbox Code Playgroud)

以及对应的翻译文件:

// your locales/starwars_en.js file

translations: {
  "Welcome, <1>User!</1>, here's your <3>broom</3>": "Welcome, <1>young padawan!</1>, here's your <3>light saber</3>",
}
Run Code Online (Sandbox Code Playgroud)

这些数字<1><3>会让你觉得是随机的,但请耐心等待:

Trans.children = [
  'Welcome, ',                        // index 0
  '<strong>User!</strong>'            // index 1
  ', please don't be ',               // index 2
  '<strong>weak</strong>',            // index 3
  ' unread messages. ',               // index 4
]
Run Code Online (Sandbox Code Playgroud)

更多信息在这里:https ://stackoverflow.com/a/62563302/537648

  • 我在这里缺少什么?似乎使用这个解决方案,您现在只能在 Component.js 中进行硬编码的英语翻译。 (4认同)

joe*_*dle 7

对于任何在React中尝试执行此操作的人(例如使用react-i18-next),请注意React 也可以转义字符串!因此,我们必须告诉国际化,并发生反应,逃跑的字符串。

  • 为了告诉i18n跳过转义,我们使用{escapeValue: false}其他显示的方式。

  • 为了告诉React跳过转义,我们使用React的dangerouslySetInnerHTML属性。

<div dangerouslySetInnerHTML={
    {__html: t('foo', {interpolation: {escapeValue: false}})}
} />
Run Code Online (Sandbox Code Playgroud)

该属性接受具有一个属性的对象__html。React故意使其丑陋,以阻止其使用,因为不逃避可能很危险。

为了安全起见,不应在该元素内使用原始用户输入。如果你确实需要当前用户输入在这里,请务必进行消毒或逃避用户的字符串,因此用户不能注入原料<>到页面中。


bor*_*kur 6

文档:

提示3:逃脱:

// given resources
{           
  'en-US': { 
    translation: { 
      key1: Not escaped __nameHTML__,
      key2: Escaped __name__ 
    } 
  }
};

i18n.t("key2", { name: '', escapeInterpolation: true }); // -> Escaped &lt;tag&gt;
i18n.t("key1", { name: '', escapeInterpolation: false }); // -> Not escaped <tag>
Run Code Online (Sandbox Code Playgroud)

在您的值中添加后缀"HTML__"将阻止转义,即使设置了选项也是如此.

您可以在init上打开转义,i18n.init({escapeInterpolation: true});或者像在示例中一样将选项传递给t函数.


小智 6

i18n.t('key',{dateStr: date, interpolation: {escapeValue: false}})
Run Code Online (Sandbox Code Playgroud)

如果date = '15/10/2020',我可以为我工作,也可以保留斜杠