i18next react Trans 组件 - 正确转义字符
i18next react Trans component - escaping characters correctly
我有一个基于 React 的应用程序并使用 i18next 的 Trans 组件进行翻译。
假设我们有一个用户注册表单,我们想通过显示以下文本来确认已经创建了一个新帐户:
User with name NAME has been created.
其中 NAME 由用户提供并以粗体显示。
我现在有以下反应代码:
<Trans i18n={i18next} i18nKey="userCreated" values={{name: 'Tom'}}>
User with name <strong>{{name}}</strong> has been created.
</Trans>
和下面的翻译字符串
"userCreated": "User with name <1>{{name}}</1> has been created.",
对于 name: 'Tom'
的简单案例,它工作正常并显示
User with name Tom has been created.
但是我想让用户在他们的名字中使用特殊字符。当我将名称更改为 Tom&Jerry
时,我得到
User with name Tom&Jerry
has been created.
经过一些研究后,我认为问题在于 i18next 和 react 都对它们的输入进行了转义,因此名称被转义了两次。我通过添加以下选项
在 i18next.init
中关闭了 i18next 转义
interpolation: {escapeValue: false},
解决了猫和老鼠的问题:
User with name Tom&Jerry has been created.
但有些输入会完全破坏它,例如设置 name: 'Tom<'
呈现如下(名称后的所有内容都是粗体):
User with name Tom has been created.
设置 name: '<Tom>'
给我:
User with name has been created.
(完全没有显示名称)。我希望它像这样呈现:
User with name <Tom>
has been created.
有没有办法让它发挥作用?
这个问题没有优雅的解决方案。问题的根源在于 Trans
组件的源代码。您要么需要为此文件创建一个补丁来更改此行为,要么自己实施一个作弊技巧。如果你打算使用作弊的解决方案,你将创建一个组件 UnescapedTrans
,它将使用 lodash 转义 HTML 个实体:
import React, { Suspense } from "react";
import { Trans } from "react-i18next";
import { unescape } from "lodash";
const getUnescapeChildrenRef = ref =>
Array.from(ref.childNodes).forEach(node => {
if (!node.innerText) {
return node;
}
node.innerText = unescape(node.innerText);
});
const UnescapedTrans = props => (
<div ref={getUnescapeChildrenRef}>
<Trans {...props} tOptions={{ interpolation: { escapeValue: true } }} />
</div>
);
我有一个基于 React 的应用程序并使用 i18next 的 Trans 组件进行翻译。
假设我们有一个用户注册表单,我们想通过显示以下文本来确认已经创建了一个新帐户:
User with name NAME has been created.
其中 NAME 由用户提供并以粗体显示。
我现在有以下反应代码:
<Trans i18n={i18next} i18nKey="userCreated" values={{name: 'Tom'}}>
User with name <strong>{{name}}</strong> has been created.
</Trans>
和下面的翻译字符串
"userCreated": "User with name <1>{{name}}</1> has been created.",
对于 name: 'Tom'
的简单案例,它工作正常并显示
User with name Tom has been created.
但是我想让用户在他们的名字中使用特殊字符。当我将名称更改为 Tom&Jerry
时,我得到
User with name
Tom&Jerry
has been created.
经过一些研究后,我认为问题在于 i18next 和 react 都对它们的输入进行了转义,因此名称被转义了两次。我通过添加以下选项
在i18next.init
中关闭了 i18next 转义
interpolation: {escapeValue: false},
解决了猫和老鼠的问题:
User with name Tom&Jerry has been created.
但有些输入会完全破坏它,例如设置 name: 'Tom<'
呈现如下(名称后的所有内容都是粗体):
User with name Tom has been created.
设置 name: '<Tom>'
给我:
User with name has been created.
(完全没有显示名称)。我希望它像这样呈现:
User with name
<Tom>
has been created.
有没有办法让它发挥作用?
这个问题没有优雅的解决方案。问题的根源在于 Trans
组件的源代码。您要么需要为此文件创建一个补丁来更改此行为,要么自己实施一个作弊技巧。如果你打算使用作弊的解决方案,你将创建一个组件 UnescapedTrans
,它将使用 lodash 转义 HTML 个实体:
import React, { Suspense } from "react";
import { Trans } from "react-i18next";
import { unescape } from "lodash";
const getUnescapeChildrenRef = ref =>
Array.from(ref.childNodes).forEach(node => {
if (!node.innerText) {
return node;
}
node.innerText = unescape(node.innerText);
});
const UnescapedTrans = props => (
<div ref={getUnescapeChildrenRef}>
<Trans {...props} tOptions={{ interpolation: { escapeValue: true } }} />
</div>
);