react-i18next:在文本中间的HTML标记中插入链接

时间:2017-04-24 12:15:36

标签: javascript reactjs i18next react-i18next

我正在使用react,i18nextreact-i18next。我希望在文本中间有一些带有HTML链接的可翻译文本,这些文本在react中进行插值,如下所示:

This is my text with <a href="{{link}}">a beautiful link</a> in the middle of the text

下面的解决方案有效,但问题是我需要在反应中插入链接,以便它不能在标签文件中进行硬编码:

"my-label": "This is my text with <a href=\"http://google.com\">a beautiful link</a> in the middle of the text"

[...]

<Interpolate i18nKey="my-label" useDangerouslySetInnerHTML />

看起来好多了:

"my-label": "This is my text with {{link}} in the middle of the text",
"link" "a beautiful link"

[...]

const { url } = props;
const link = <a href={url}>{t('link')}</a>

<Interpolate i18nKey="my-label" link={link} />

可能是解决方案,但是应用程序被翻译成多种语言并且翻译质量非常重要,因此我更倾向于将整个文本放在一行中用于翻译(这对于有案例的语言尤为重要)。

有什么方法可以像这样工作(或者有什么方法可以完全不同地解决它)?

"my-label": "This is my text with <a href=\"{{link}}\">a beautiful link</a> in the middle of the text"

[...]

const { url } = props;

<Interpolate i18nKey="my-label" useDangerouslySetInnerHTML link={url} />

3 个答案:

答案 0 :(得分:4)

使用react-i18next v4.4.0,我们引入了一个新组件 Trans

<Trans i18nKey="optionalKey">See the <Link to="/more">description</Link> below.</Trans>

json将是:See the <1>description</1> below.

甚至更复杂:

<Trans i18nKey="userMessagesUnread" count={count}>
Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>

此处记录了新功能:https://react.i18next.com/components/trans-component.html

答案 1 :(得分:0)

这是react-intlreact-i18next的常见问题 - 两个lib对内联组件和翻译内部的富文本格式的支持非常有限(我已经用here描述了它更多细节)。

如果你还在项目的开头,你可能想要考虑不同的i18n库 - js-lingui(免责声明:我是作者)。它是第一个(也是迄今为止唯一的)完全支持内联组件的库。

你只需写:

<Trans>See the <Link to="/more">description</Link> below.</Trans>

您的翻译人员将使用消息See the <0>description</0> below.

唯一的价格是你需要使用额外的babel插件,这使它成为可能。

答案 2 :(得分:-1)

<Interpolate i18nKey="my-label" useDangerouslySetInnerHTML link={url} /> 几周前添加并允许插入包含html片段的翻译 - 只要知道如果url来自userinput且包含恶意代码(xss攻击),这是危险的

我认为这是去年增加的:https://github.com/i18next/react-i18next/pull/195/files

但是这将默认包围{{link}}之前/之后的每个部分的跨度,这可能不是你需要的...但解决方案相当简单 - 不要使用插值组件而是使用常规插值功能:

<div dangerouslySetInnerHTML={t('my-label', { link: yourURL }} />