i18next-react 和自定义格式

问题描述 投票:0回答:3

我确实使用 i18next-react 并尝试使用格式化。 所以我在初始化格式中进行了这样的设置:

i18n.use(initReactI18next).init(
  {
    ...
    interpolation: {
      escapeValue: false,
      // eslint-disable-next-line no-unused-vars
      format: function (value, format, lng) {
        if (format === 'uppercase') return value.toUpperCase();
        if (format === 'lowercase') return value.toLowerCase();
        if (format === 'capitalize') return `${value.substr(0, 1).toUpperCase()}${value.substr(1)}`;
        return value;
      },
    },
    ...
  },

如果我在我的反应组件中这样做:

import i18next from 'i18next';
i18next.format('edit', 'capitalize'),

它的工作原理与预期一致...单词 edit 变为大写字母。

但是,我如何将它与我自己的翻译一起使用:

t('edit')
我想知道是否有一种方法可以使用react-i18next而不是i18next包来调用格式化

如果我尝试使用:

t('{{edit, capitalize}}'),
,我收到此错误: enter image description here

我尝试的至少是在我的 t()-Method 中决定在该字符串上使用给定的格式。

reactjs react-i18next
3个回答
7
投票

好的,我找到了两个解决方案。

TLDR;第二个,可能是更好的一个!

第一个解决方案

语言文件

在我的 common.js 中,我添加了某种

Meta-Formater
字符串,如下所示:

{
  "uppercase": "{{value, uppercase}}",
  "capitalize": "{{value, capitalize}}",
  "lowercase": "{{value, lowercase}}",
}

i18n.js 配置

我在配置中的自定义格式如下所示:

i18n.use(initReactI18next).init(
  {
    ...
    interpolation: {
      escapeValue: false,
      // eslint-disable-next-line no-unused-vars
      format: function (value, format, lng) {
        if (format === 'uppercase') return value.toUpperCase();
        if (format === 'lowercase') return value.toLowerCase();
        if (format === 'capitalize') return `${value.substr(0, 1).toUpperCase()}${value.substr(1)}`;
        return value;
      },
    },
    ...
  },

如何使用

在我的组件中我这样使用它:

t('common:capitalize', { value: t('common:edit') })

它的作用:我使用在 common.js 中声明的键来格式化作为参数粘贴到其中的任何值

value

在我的组件中,我粘贴了

common:edit
的静态翻译值。对于 DE,它是
bearbeiten
,现在将由
common:capitalize
大写。

第二个解决方案(更好的一个?!?)

您不需要在 common.js 中定义这样的“Meta-Formater”,只需定义上一主题中描述的

i18n.js config
即可。

然后在您的组件中,您需要额外导入

i18next
并像这样使用它:

i18next.format(t('common:settings'), 'capitalize'),

在我看来,此解决方案是更干净的解决方案,但有唯一的缺点,您必须添加额外的导入: enter image description here


0
投票

你应该定义一个自定义函数;让changeCase成为那个函数

const changeCase = (str, isLower = false) =>
  isLower ? str.toLowerCase() : str.toUpperCase() // you can extend this function to suit your needs

在你的翻译中你可以这样做:

changeCase(t('edit')) // here it will uppercase the whole string
changeCase(t('edit'), true) // will lowercase the whole string

0
投票

如果您像我一样来这里寻求实现

i18next
的格式化程序,并且您正在使用
i18next
来满足多种语言的需求,那么您应该避免使用
capitalize
uppercase
lowercase
等格式化程序。

但是,如果您只是使用

i18n
来表示根据您要呈现的用户/客户端而有所不同的英语术语,那么 这个答案就足够了

为什么应该避免使用
capitalize
uppercase
等格式化程序

不同的语言有不同的大小写规则,应用简单的“首字母大写”方法可能不遵守这些规则:

以下是一些示例:

德语 (
ß
SS
)

在德语中,有一个字符

"ß"
(Eszett),它没有大写形式。将
"straße"
(街道)转换为标题大小写时,如果仅第一个字母大写,则正确的转换为
"Straße"
。但是,如果整个单词需要大写,则
"straße"
会变为
"STRASSE"
(而不是
"STRAßE"
)。

土耳其语(无点
I
和点式
İ

土耳其语有两个不同版本的字母

"I"

  • 无点
    "ı"
  • 虚线
    "İ"

小写

"i"
大写时变为
"İ"
,小写
"ı"
变为
"I"

使用通用大写格式化程序可能会将

"istanbul"
变成
"Istanbul"
(这是正确的),但在适用土耳其语特定规则的其他上下文中,可能会将包含
"ı"
"i"
的单词大写错误。

法语(重音保持大写)

在法语中,即使是大写字母,也应保留重音符号。例如,

"élève"
应大写为
"Élève"
,并完全大写为
"ÉLÈVE"

基本的大写功能可能会删除重音符号,从而导致

"Eleve"
"ELEVE"
,这在法语中是不正确的。

希腊语(西格玛变奏)

在希腊语中,字母 sigma (

σ
) 当出现在单词末尾 (
ς
) 时具有特殊形式。将文本转换为大写时,仍应考虑最终形式。

使用格式化程序在不考虑上下文的情况下将希腊文本大写可能会错误地将

"κόσμος"
转换为
"Κόσμος"
(仅大写第一个字母),但无法处理 sigma 改变形状的情况。

荷兰语(使用
"ij"

在荷兰语中,

"ij"
被视为单个单位,通常一起大写,如
"IJsselmeer"
(荷兰的一个湖)。

仅将第一个字母大写会导致

"Ijsselmeer"
,这是不正确的。


我确信还有很多例子我什至没有在这里提及,所以这就是为什么我们应该避免依赖像

capitalize
uppercase
lowercase
等格式化程序。

解决方案

这可能看起来很痛苦,但正确处理此问题的最安全方法是为您需要的所有格式化案例提供翻译。

让我们使用上面的德语示例,将单词

"street"
的英语翻译为德语。如果您需要满足
capitalize
uppercase
lowercase
。您的
de-DE.json
文件如下所示(假设您使用英语作为基本键):

{
  "street": "straße",
  "Street": "Straße",
  "STREET": "STRASSE",
}
© www.soinside.com 2019 - 2024. All rights reserved.