Grafana国际化:多语言支持和本地化配置
在全球化的今天,数据可视化平台需要服务于来自不同地区、使用不同语言的用户。Grafana作为一款开源的可观测性和数据可视化平台,其国际化(Internationalization,简称i18n)能力至关重要。本文将深入探讨Grafana的多语言支持架构、本地化配置方法、翻译工作流以及开发者实践指南,帮助用户和开发者充分利用Grafana的国际化特性,打造无缝的多语言用户体验。
Grafana国际化架构概览
Grafana的国际化系统基于现代化的前端框架构建,采用业界成熟的国际化解决方案,确保平台能够灵活支持多种语言,并方便开发者和翻译者协作。
技术选型与核心组件
Grafana前端采用i18next框架作为国际化核心引擎,配合react-i18next实现React组件的国际化。这种组合提供了强大的翻译管理能力,包括:
- 键值对翻译存储
- 复数形式处理
- 插值和格式化
- 嵌套翻译结构
- 语言检测与切换
国际化相关的核心代码集中在以下目录:
- 翻译文件存储:public/locales/ - 包含各语言的翻译JSON文件
- 国际化文档:contribute/internationalization.md - 详细的国际化开发指南
- 前端工具:app/core/internationalization/ - 提供
<Trans />组件和t()函数等API
国际化工作流
Grafana的国际化工作流采用"代码标记-提取-翻译-集成"的标准流程,具体如下:
这种工作流确保了开发和翻译过程的分离与协作,同时通过自动化工具链减少人工操作错误。
多语言支持现状
Grafana目前已支持多种语言,覆盖全球主要使用人群。通过查看public/locales/目录,可以了解当前支持的语言列表:
public/locales/ru-RU # 俄语
public/locales/pt-PT # 葡萄牙语(葡萄牙)
public/locales/es-ES # 西班牙语(西班牙)
public/locales/de-DE # 德语
public/locales/hu-HU # 匈牙利语
public/locales/id-ID # 印度尼西亚语
public/locales/zh-Hant # 中文(繁体)
public/locales/ko-KR # 韩语
public/locales/pt-BR # 葡萄牙语(巴西)
public/locales/it-IT # 意大利语
public/locales/sv-SE # 瑞典语
public/locales/ja-JP # 日语
public/locales/cs-CZ # 捷克语
public/locales/zh-Hans # 中文(简体)
public/locales/fr-FR # 法语
public/locales/pl-PL # 波兰语
public/locales/nl-NL # 荷兰语
public/locales/en-US # 英语(美国) - 默认语言
public/locales/tr-TR # 土耳其语
翻译文件结构
每个语言的翻译文件遵循统一的JSON结构,以中文(简体)为例(public/locales/zh-Hans/grafana.json):
{
"_comment": "代码是英语短语的真实来源。应直接在组件中对它们进行更新,并在此文件中指定其他复数形式。",
"access-control": {
"add-permission": {
"role-label": "角色",
"serviceaccount-label": "服务帐户",
"team-label": "团队",
"title": "添加权限:",
"user-label": "用户"
},
"permissions": {
"add-label": "添加权限",
"no-permissions": "没有任何权限",
"role": "角色",
"serviceaccount": "服务帐户",
"team": "团队",
"title": "权限",
"user": "用户"
}
},
"alerting": {
"alert": {
"alert-state": "提醒状态",
"evaluation": "评估",
"last-evaluated": "上次评估",
"rule": "规则"
}
}
// ... 更多翻译内容
}
这种嵌套结构使用点分隔的键(如access-control.add-permission.title)来组织翻译文本,使相关短语归类到特定功能模块下,提高可维护性。
用户语言设置与切换
Grafana允许用户根据自己的语言偏好设置界面语言。语言选择通常在用户个人资料设置中提供,系统会将用户选择存储在浏览器本地存储或用户配置文件中。
语言检测与回退机制
Grafana采用以下优先级确定显示语言:
- 用户明确选择的语言偏好
- 浏览器的
Accept-Language头部 - 默认语言(英语,en-US)
当某个短语在用户选择的语言中没有翻译时,系统会自动回退到英语版本,确保用户始终能看到有意义的内容,而不是缺失的翻译键。
本地化日期和数字格式
除了文本翻译外,Grafana还支持根据语言环境自动调整日期、时间和数字格式。例如:
- 日期格式:中文环境显示"2023年10月5日",英文环境显示"Oct 5, 2023"
- 时间格式:中文环境使用24小时制,某些语言环境使用12小时制
- 数字格式:不同语言环境使用不同的千位分隔符和小数点符号
这些本地化格式由前端框架根据当前语言环境自动处理,无需开发者额外编码。
开发者指南:标记可翻译内容
对于Grafana开发者,正确标记可翻译内容是实现国际化的关键步骤。根据contribute/internationalization.md文档,有两种主要方式标记可翻译文本。
React组件中使用<Trans />组件
对于JSX中的文本内容,应使用<Trans />组件包裹,并指定唯一的i18nKey:
import { Trans } from 'app/core/internationalization';
// 基础用法
<Trans i18nKey="dashboard.header.refresh-label">Refresh dashboard</Trans>
// 带变量插值
<Trans i18nKey="search-page.results-title">
Results for {{ term }}
</Trans>
// 带HTML或React组件
<Trans i18nKey="page.explainer">
Click <button>here</button> to learn more.
</Trans>
注意事项:
i18nKey必须是静态字符串,不能是动态生成的- 组件内部结构(如HTML标签、React组件)会被i18next自动编号处理
- 变量插值使用
{{ variable }}语法
JavaScript代码中使用t()函数
对于非JSX文本(如属性、工具函数返回值),应使用t()函数:
import { t } from "app/core/internationalization"
// 基础用法
const placeholder = t('form.username-placeholder', 'Username');
// 带变量插值
const greeting = t('page.greeting', 'Hello {{ username }}', { username: user.name });
// 复数形式
const message = t('inbox.heading', 'You have {{count}} messages', { count: messages.length });
复数形式处理
不同语言有不同的复数规则,Grafana通过i18next支持复杂的复数形式处理:
// 代码中
<Trans i18nKey="inbox.heading" count={messages.length}>
You have {{ count: messages.length }} messages
</Trans>
// 翻译文件中 (en-US/grafana.json)
{
"inbox": {
"heading_one": "You have {{count}} message",
"heading_other": "You have {{count}} messages"
}
}
i18next会根据不同语言的复数规则(如中文没有复数变化,阿拉伯语有6种复数形式)自动选择正确的翻译。
提取翻译文本
完成代码标记后,需运行以下命令提取文本到英语翻译文件:
make i18n-extract
该命令会扫描所有代码文件,提取使用<Trans />和t()标记的文本,并更新public/locales/en-US/grafana.json文件。
翻译管理与Crowdin集成
Grafana使用Crowdin作为翻译管理平台,协调全球翻译者贡献翻译。根据contribute/internationalization.md,Grafana目前不直接接受翻译PR,而是通过Crowdin进行翻译管理。
添加新语言流程
要为Grafana添加新语言,需完成以下步骤:
- 在Crowdin项目中添加目标语言
- 如Crowdin语言代码与IETF语言标签不同,配置语言映射
- 运行Crowdin同步工作流生成初始翻译文件
- 更新public/app/core/internationalization/constants.ts添加新语言常量
- 创建PR合并新语言支持
翻译质量保证
为确保翻译质量,Grafana采用以下措施:
- 每个翻译都需要经过审核
- 关键功能区域的翻译有专门的语言负责人
- 定期从Crowdin同步经过审核的翻译
- 社区反馈机制,允许用户报告翻译问题
本地化配置实例
以下是几个常见的本地化配置场景,展示如何在Grafana中实现特定的国际化需求。
自定义日期格式
虽然Grafana自动处理大部分本地化格式,但有时需要自定义日期显示:
import { useLocale } from 'app/core/internationalization';
import { format } from 'date-fns';
import { zhCN, enUS } from 'date-fns/locale';
function LocalizedDate({ date }) {
const { locale } = useLocale();
const dateLocale = locale === 'zh-Hans' ? zhCN : enUS;
return (
<span>
{format(date, 'PPPP', { locale: dateLocale })}
</span>
);
}
语言切换组件
以下是一个简单的语言切换器组件示例:
import { useLocale } from 'app/core/internationalization';
const LanguageSelector = () => {
const { locale, changeLocale } = useLocale();
const supportedLocales = [
{ code: 'en-US', name: 'English' },
{ code: 'zh-Hans', name: '简体中文' },
{ code: 'es-ES', name: 'Español' },
{ code: 'de-DE', name: 'Deutsch' },
];
return (
<select
value={locale}
onChange={(e) => changeLocale(e.target.value)}
>
{supportedLocales.map(lang => (
<option key={lang.code} value={lang.code}>
{lang.name}
</option>
))}
</select>
);
};
测试不同语言环境
开发者可以通过以下方式测试不同语言环境:
- 修改用户设置中的语言偏好
- 使用浏览器开发者工具覆盖
Accept-Language头部 - 启动Grafana时设置
GF_DEFAULT_LOCALE环境变量
# 开发环境测试特定语言
GF_DEFAULT_LOCALE=zh-Hans make run
高级主题:国际化最佳实践
避免硬编码文本
所有用户可见的文本都应使用<Trans />或t()标记,避免直接写死在代码中:
// 错误 ❌
<div>Welcome to Grafana</div>
// 正确 ✅
<Trans i18nKey="welcome.message">Welcome to Grafana</Trans>
使用有意义的i18nKey
遵循一致的i18nKey命名规范可以提高可维护性:
// 推荐格式:[feature].[component].[purpose]
dashboard.header.title
search.results.count
alert.message.error
button.submit.label
menu.file.new
避免使用无意义的键名如text1、msg2等,或过长的描述性键名。
处理动态内容
对于动态生成的内容(如用户输入、API返回数据),通常不需要翻译,但可能需要根据语言环境进行格式化:
// 日期格式化
formatDate(user.createdAt, { locale });
// 数字格式化
new Intl.NumberFormat(locale).format(metricValue);
// 货币格式化
new Intl.NumberFormat(locale, {
style: 'currency',
currency: 'USD'
}).format(price);
国际化测试
国际化测试应包括:
- 确认所有文本都已正确标记为可翻译
- 验证翻译提取工具能正确提取所有标记文本
- 检查RTL(从右到左)语言的布局是否正确
- 测试不同语言环境下的复数形式
- 验证缺失翻译时的回退机制是否正常工作
问题排查与常见挑战
翻译不显示的排查步骤
如果某个翻译未正确显示,可按以下步骤排查:
- 确认
i18nKey在代码中和翻译文件中完全一致 - 检查对应语言的翻译文件是否包含该键
- 运行
make i18n-extract确保最新的键已提取 - 清除浏览器缓存或使用无痕模式测试
- 查看浏览器控制台是否有i18n相关错误
处理长文本翻译
某些语言(如德语、俄语)的翻译文本比英语长30-50%,可能导致UI布局问题:
维护翻译一致性
大型项目中保持翻译一致性是挑战,可通过以下方式解决:
- 建立翻译术语表
- 使用一致的
i18nKey命名规范 - 定期审查常用短语的翻译
- 利用Crowdin的翻译记忆功能
未来发展方向
Grafana的国际化功能持续演进,未来可能的发展方向包括:
- 支持更多语言,特别是小语种
- 改进翻译工作流,缩短从代码提交到翻译可用的周期
- 提供更好的翻译质量指标和反馈机制
- 增强本地化格式支持,如自定义日期时间格式
- 改进RTL(从右到左)语言的支持
- 提供更丰富的国际化API,简化开发者工作
总结
Grafana的国际化架构为全球用户提供了良好的多语言支持,通过i18next框架和标准化的开发流程,实现了文本标记、提取、翻译和集成的完整工作流。对于用户,Grafana提供了直观的语言切换和本地化体验;对于开发者,完善的文档和工具链使国际化开发变得简单高效。
随着Grafana的不断发展,其国际化能力将持续增强,更好地服务于全球各地的用户和组织。无论是普通用户还是开发者,了解和利用Grafana的国际化特性,都能极大提升产品体验和开发效率。
要深入了解Grafana国际化,建议参考以下资源:
- 官方国际化文档:contribute/internationalization.md
- i18next文档:https://www.i18next.com/
- react-i18next文档:https://react.i18next.com/
- Grafana本地化JSON文件:public/locales/
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



