mirror of
https://github.com/grafana/grafana.git
synced 2024-12-28 01:41:24 -06:00
I18n: Add Chinese (Simplified) (#56739)
* Prevent _old.json files from being created * Add contrib docs for adding new locale * add chinese (simplified)
This commit is contained in:
parent
85e3ed491d
commit
719769ee7c
@ -38,6 +38,18 @@ const ErrorMessage = ({ id, message }) => <Trans id={`errors.${id}`}>There was a
|
||||
|
||||
3. Before submitting your PR, run the `yarn i18n:extract` command to extract the messages you added into the `messages.po` file and make them available for translation.
|
||||
|
||||
## How to add a new language
|
||||
|
||||
1. Add new locale in Crowdin and sync files to repo
|
||||
1. Grafana OSS Crowdin project -> "dot dot dot" menu in top right -> Target languages
|
||||
2. Grafana OSS Crowdin project -> Integrations -> Github -> Sync Now
|
||||
3. If Crowdin's locale code is different from our IETF language tag, add a custom mapping in Project Settings -> Language mapping
|
||||
2. Update `public/app/core/internationalization/constants.ts` (add new constant, and add to `VALID_LOCALES`)
|
||||
3. Update `public/app/core/internationalization/index.tsx` to add the message loader for the new locale
|
||||
4. Update `public/app/core/components/SharedPreferences/SharedPreferences.tsx` to add the new locale to the options.
|
||||
5. Update `public/locales/i18next-parser.config.js` to add the new locale to `locales`
|
||||
6. Run `yarn i18n:extract` and commit the result
|
||||
|
||||
## How translations work in Grafana
|
||||
|
||||
Grafana uses the [LinguiJS](https://github.com/lingui/js-lingui) framework for managing translating phrases in the Grafana frontend. It:
|
||||
|
@ -19,7 +19,13 @@ import {
|
||||
} from '@grafana/ui';
|
||||
import { DashboardPicker } from 'app/core/components/Select/DashboardPicker';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { ENGLISH_US, FRENCH_FRANCE, PSEUDO_LOCALE, SPANISH_SPAIN } from 'app/core/internationalization/constants';
|
||||
import {
|
||||
CHINESE_SIMPLIFIED,
|
||||
ENGLISH_US,
|
||||
FRENCH_FRANCE,
|
||||
PSEUDO_LOCALE,
|
||||
SPANISH_SPAIN,
|
||||
} from 'app/core/internationalization/constants';
|
||||
import { PreferencesService } from 'app/core/services/PreferencesService';
|
||||
import { UserPreferencesDTO } from 'app/types';
|
||||
|
||||
@ -43,15 +49,19 @@ const languages: Array<SelectableValue<string>> = [
|
||||
},
|
||||
{
|
||||
value: ENGLISH_US,
|
||||
label: t('common.locale.en', 'English'),
|
||||
label: t('common.locale.en-US', 'English'),
|
||||
},
|
||||
{
|
||||
value: SPANISH_SPAIN,
|
||||
label: t('common.locale.es', 'Spanish'),
|
||||
label: t('common.locale.es-ES', 'Spanish'),
|
||||
},
|
||||
{
|
||||
value: FRENCH_FRANCE,
|
||||
label: t('common.locale.fr', 'French'),
|
||||
label: t('common.locale.fr-FR', 'French'),
|
||||
},
|
||||
{
|
||||
value: CHINESE_SIMPLIFIED,
|
||||
label: t('common.locale.zh-Hans', 'Chinese (Simplified)'),
|
||||
},
|
||||
// TODO: dev only
|
||||
{
|
||||
|
@ -1,8 +1,9 @@
|
||||
export const ENGLISH_US = 'en-US';
|
||||
export const FRENCH_FRANCE = 'fr-FR';
|
||||
export const SPANISH_SPAIN = 'es-ES';
|
||||
export const CHINESE_SIMPLIFIED = 'zh-Hans';
|
||||
export const PSEUDO_LOCALE = 'pseudo-LOCALE';
|
||||
|
||||
export const DEFAULT_LOCALE = ENGLISH_US;
|
||||
|
||||
export const VALID_LOCALES: string[] = [ENGLISH_US, FRENCH_FRANCE, SPANISH_SPAIN, PSEUDO_LOCALE];
|
||||
export const VALID_LOCALES: string[] = [ENGLISH_US, FRENCH_FRANCE, SPANISH_SPAIN, CHINESE_SIMPLIFIED, PSEUDO_LOCALE];
|
||||
|
@ -2,12 +2,21 @@ import i18n, { BackendModule, ResourceKey } from 'i18next';
|
||||
import React from 'react';
|
||||
import { Trans as I18NextTrans, initReactI18next } from 'react-i18next'; // eslint-disable-line no-restricted-imports
|
||||
|
||||
import { DEFAULT_LOCALE, ENGLISH_US, FRENCH_FRANCE, SPANISH_SPAIN, PSEUDO_LOCALE, VALID_LOCALES } from './constants';
|
||||
import {
|
||||
DEFAULT_LOCALE,
|
||||
ENGLISH_US,
|
||||
FRENCH_FRANCE,
|
||||
SPANISH_SPAIN,
|
||||
PSEUDO_LOCALE,
|
||||
VALID_LOCALES,
|
||||
CHINESE_SIMPLIFIED,
|
||||
} from './constants';
|
||||
|
||||
const messageLoaders: Record<string, () => Promise<ResourceKey>> = {
|
||||
[ENGLISH_US]: () => import('../../../locales/en-US/grafana.json'),
|
||||
[FRENCH_FRANCE]: () => import('../../../locales/fr-FR/grafana.json'),
|
||||
[SPANISH_SPAIN]: () => import('../../../locales/es-ES/grafana.json'),
|
||||
[CHINESE_SIMPLIFIED]: () => import('../../../locales/zh-Hans/grafana.json'),
|
||||
[PSEUDO_LOCALE]: () => import('../../../locales/pseudo-LOCALE/grafana.json'),
|
||||
};
|
||||
|
||||
|
@ -2,9 +2,10 @@
|
||||
"common": {
|
||||
"locale": {
|
||||
"default": "Default",
|
||||
"en": "English",
|
||||
"es": "Spanish",
|
||||
"fr": "French"
|
||||
"en-US": "English",
|
||||
"es-ES": "Spanish",
|
||||
"fr-FR": "French",
|
||||
"zh-Hans": "Chinese (Simplified)"
|
||||
},
|
||||
"save": "Save"
|
||||
},
|
||||
|
@ -2,9 +2,10 @@
|
||||
"common": {
|
||||
"locale": {
|
||||
"default": "",
|
||||
"en": "",
|
||||
"es": "",
|
||||
"fr": ""
|
||||
"en-US": "",
|
||||
"es-ES": "",
|
||||
"fr-FR": "",
|
||||
"zh-Hans": ""
|
||||
},
|
||||
"save": ""
|
||||
},
|
||||
|
@ -2,9 +2,10 @@
|
||||
"common": {
|
||||
"locale": {
|
||||
"default": "",
|
||||
"en": "",
|
||||
"es": "",
|
||||
"fr": ""
|
||||
"en-US": "",
|
||||
"es-ES": "",
|
||||
"fr-FR": "",
|
||||
"zh-Hans": ""
|
||||
},
|
||||
"save": ""
|
||||
},
|
||||
|
@ -2,7 +2,7 @@ module.exports = {
|
||||
// Default namespace used in your i18next config
|
||||
defaultNamespace: 'grafana',
|
||||
|
||||
locales: ['en-US', 'fr-FR', 'es-ES', 'pseudo-LOCALE'],
|
||||
locales: ['en-US', 'fr-FR', 'es-ES', "zh-Hans", 'pseudo-LOCALE'],
|
||||
|
||||
output: './public/locales/$LOCALE/$NAMESPACE.json',
|
||||
|
||||
@ -10,6 +10,8 @@ module.exports = {
|
||||
|
||||
sort: true,
|
||||
|
||||
createOldCatalogs: false,
|
||||
|
||||
// Don't include default values for English, they'll remain in the source code
|
||||
skipDefaultValues: (locale) => locale !== 'en-US',
|
||||
};
|
||||
|
@ -2,9 +2,10 @@
|
||||
"common": {
|
||||
"locale": {
|
||||
"default": "Đęƒäūľŧ",
|
||||
"en": "Ēʼnģľįşĥ",
|
||||
"es": "Ŝpäʼnįşĥ",
|
||||
"fr": "Fřęʼnčĥ"
|
||||
"en-US": "Ēʼnģľįşĥ",
|
||||
"es-ES": "Ŝpäʼnįşĥ",
|
||||
"fr-FR": "Fřęʼnčĥ",
|
||||
"zh-Hans": "Cĥįʼnęşę (Ŝįmpľįƒįęđ)"
|
||||
},
|
||||
"save": "Ŝävę"
|
||||
},
|
||||
@ -441,4 +442,4 @@
|
||||
"user-sessions": {
|
||||
"loading": "Ŀőäđįʼnģ şęşşįőʼnş..."
|
||||
}
|
||||
}
|
||||
}
|
@ -2,9 +2,10 @@
|
||||
"common": {
|
||||
"locale": {
|
||||
"default": "",
|
||||
"en": "",
|
||||
"es": "",
|
||||
"fr": ""
|
||||
"en-US": "",
|
||||
"es-ES": "",
|
||||
"fr-FR": "",
|
||||
"zh-Hans": ""
|
||||
},
|
||||
"save": ""
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user