Skip to main content

国际化(实验)

概览

Backstage 核心功能为插件提供国际化功能。 其底层库是i18next与一些额外的 Backstage 类型脚本魔法,以确保键的类型安全。

对于插件开发人员

创建插件时,您可以使用createTranslationRef来定义插件的所有信息,例如

import { createTranslationRef } from '@backstage/core-plugin-api/alpha';

/** @alpha */
export const myPluginTranslationRef = createTranslationRef({
id: 'plugin.my-plugin',
messages: {
indexPage: {
title: 'All your components',
createButtonTitle: 'Create new component',
},
entityPage: {
notFound: 'Entity not found',
},
},
});

并在组件中使用这些信息,如

import { useTranslationRef } from '@backstage/core-plugin-api/alpha';

const { t } = useTranslationRef(myPluginTranslationRef);

return (
<PageHeader title={t('indexPage.title')}>
<Button onClick={handleCreateComponent}>
{t('indexPage.createButtonTitle')}
</Button>
</PageHeader>
);

您将看到初始字典结构和嵌套是如何转换为点符号的,因此我们鼓励camelCase在键名中使用,并依靠嵌套结构来分隔键。

i18n信息和密钥指南

的应用程序接口i18n由于消息和密钥是一个非常灵活的 API,因此要正确处理它们可能非常棘手。 我们为您提供了一些指南,以帮助您开始翻译插件,并鼓励您在考虑翻译插件时采用良好的做法:

关键名称

在定义报文时,建议使用嵌套结构来表示翻译中的语义层次结构。 这样可以更好地组织和理解结构,例如

export const myPluginTranslationRef = createTranslationRef({
id: 'plugin.my-plugin',
messages: {
dashboardPage: {
title: 'All your components',
subtitle: 'Create new component',
widgets: {
weather: {
title: 'Weather',
description: 'Shows the weather',
},
calendar: {
title: 'Calendar',
description: 'Shows the calendar',
},
},
},
entityPage: {
notFound: 'Entity not found',
},
},
});

考虑的是内容的语义位置,而不是文本内容本身。 将相关的翻译归类到一个共同的前缀下,并使用嵌套来表示应用程序不同部分之间的关系。 最好在扩展、页面部分或可视化范围和体验下开始归类。

译文应尽可能避免使用自己的文本内容作为关键字,因为如果译文发生变化,这可能会导致混乱。 相反,最好使用描述文本位置或用法的关键字。

常用键名

这个列表会随着时间的推移而不断增加,但下面是一些常见的关键名称和模式的例子,我们鼓励你尽可能使用它们:

  • ${page}.title * ${page}.subtitle * ${page}.description * ${page}.header.title

关键重复使用

不鼓励在多个地方重复使用同一个关键字。 这有助于防止含糊不清,并尽可能清楚地说明每个关键字的用法。 可以考虑创建重复的关键字,并将其归入语义部分。

扁平键

避免在根级别使用扁平键结构,因为这会导致命名冲突,并使翻译文件更难管理和随着时间的推移而变化。 相反,应使用共同的前缀对翻译进行分组。

export const myPluginTranslationRef = createTranslationRef({
id: 'plugin.my-plugin',
messages: {
// this is BAD
title: 'My page',
subtitle: 'My subtitle',
// this is GOOD
dashboardPage: {
header: {
title: 'All your components',
subtitle: 'Create new component',
},
},
},
});

复数

i18next库内置了对复数化的支持。文件.

我们鼓励您使用这一功能,避免为复数内容创建不同的键前缀。 例如

export const myPluginTranslationRef = createTranslationRef({
id: 'plugin.my-plugin',
messages: {
dashboardPage: {
title: 'All your components',
subtitle: 'Create new component',
cards: {
title_one: 'You have one card',
title_two: 'You have two cards',
title_other: 'You have many cards ({{count}})',
},
},
entityPage: {
notFound: 'Entity not found',
},
},
});

对于应用程序开发人员来说,覆盖插件信息

在应用程序中,您既可以覆盖默认信息,也可以注册其他语言的翻译:

const app = createApp({
+ __experimentalTranslations: {
+ availableLanguages: ['en', 'zh'],
+ resources: [
+ createTranslationMessages({
+ ref: myPluginTranslationRef,
+ messages: {
+ 'indexPage.createButtonTitle': 'Create new entity',
+ },
+ }),
+ createTranslationResource({
+ ref: myPluginTranslationRef,
+ messages: {
+ zh: () => import('./translations/zh'),
+ },
+ }),
+ ],
+ },
})