mirror of
https://github.com/home-assistant/developers.home-assistant.git
synced 2025-07-14 12:56:30 +00:00
Move and extract internationalization/translations (#506)
This commit is contained in:
parent
5647aefda3
commit
122f7bfa14
19
docs/internationalization.md
Normal file
19
docs/internationalization.md
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
title: "Internationalization"
|
||||
---
|
||||
|
||||
The Home Assistant internationalization project includes preparing platforms and the frontend for localization, as well as the actual translation of localized strings.
|
||||
|
||||
Some components and platforms will have strings that need to be localized specifically for that platform. These strings are managed in the core [home-assistant](https://github.com/home-assistant/home-assistant) repository. The Home Assistant backend will serve strings to the clients based on the loaded components in the running instance.
|
||||
|
||||
There are also localizable strings that exist only on the frontend. These strings are managed in the [home-assistant-polymer](https://github.com/home-assistant/home-assistant-polymer) repository. These strings are stored with the frontend and don’t depend on the backend configuration.
|
||||
|
||||
| Type | Location |
|
||||
| ----------------- | -------- |
|
||||
| Entity states | Core |
|
||||
| Config flows | Core |
|
||||
| Options flows | Core |
|
||||
| Device automation | Core |
|
||||
| Text in UI | Frontend |
|
||||
|
||||
Our strings are translated by the community using the online translation tool [Lokalise](https://lokalise.co/).
|
119
docs/internationalization/core.md
Normal file
119
docs/internationalization/core.md
Normal file
@ -0,0 +1,119 @@
|
||||
---
|
||||
title: "Backend Localization"
|
||||
---
|
||||
|
||||
## Translation Strings
|
||||
|
||||
Platform translation strings are stored as JSON in the [home-assistant](https://github.com/home-assistant/home-assistant) repository. These files must be located adjacent to the component/platform they belong to. Components must have their own directory, and the file is simply named `strings.json` in that directory. For platforms, they are named `strings.<platform name>.json` in the platform directory. This file will contain the different strings that will be translatable.
|
||||
|
||||
### `strings.json`
|
||||
|
||||
The `strings.json` contains translations for different things that the integration offers that need to be translated.
|
||||
|
||||
| Category | Description |
|
||||
| ------------------- | ------------------------------------------------- |
|
||||
| `title` | Title of the integration. |
|
||||
| `state` | States of the integration, keyed by device class. |
|
||||
| `config` | Translations for the config flow. |
|
||||
| `options` | Translations for the options flow. |
|
||||
| `device_automation` | Translations for the device automations. |
|
||||
|
||||
#### Title
|
||||
|
||||
This category is just a string: the translation of the integration name. This key is optional and Home Assistant will fallback to the integration name if it is omitted. Only include this if it's not a product brand.
|
||||
|
||||
#### State
|
||||
|
||||
If your integration provides entities under it's domain, you will want to translate the states. You do this by offering a `state` dictionary, that contains translations for states with different device classes. The key `_` is used for entities without a device class.
|
||||
|
||||
```json
|
||||
{
|
||||
"state": {
|
||||
"problem": {
|
||||
"off": "OK",
|
||||
"on": "Problem"
|
||||
},
|
||||
"safety": {
|
||||
"off": "Safe",
|
||||
"on": "Unsafe"
|
||||
},
|
||||
"_": {
|
||||
"off": "[%key:common::state::off%]",
|
||||
"on": "[%key:common::state::on%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Config / Options
|
||||
|
||||
The translation strings for the configuration flow handler are defined under the `config` key. An example strings file below describes the different supported keys:
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
// Optional. Title to show in list. Only will be rendered if placeholders required
|
||||
"flow_title": "Discovered Device ({host})",
|
||||
"step": {
|
||||
"init": {
|
||||
// Optional. Will show the integration name if omitted
|
||||
"title": "The user visible title of the `init` step.",
|
||||
// Optional
|
||||
"description": "Markdown that is shown with the step.",
|
||||
"data": {
|
||||
"api_key": "The label for the `api_key` input field"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "This message will be displayed if `invalid_api_key` is returned as a flow error."
|
||||
},
|
||||
"abort": {
|
||||
"stale_api_key": "This message will be displayed if `stale_api_key` is returned as the abort reason."
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `strings.sensor.json`
|
||||
|
||||
Integrations can provide translations for states of its entities under other integrations like sensor. To do this, the entity will need a custom device class that starts with `<domain>__<custom name>`. You can then provide translations that will only be applied for your entity. Note that you cannot customize your translation when you use an official device class. Those are standardized.
|
||||
|
||||
To differentiate entities and their translations, provide different device classes. The following example `strings.sensor.json` is for a Moon sensor entity with the `moon__phase` device class:
|
||||
|
||||
```json
|
||||
{
|
||||
"state": {
|
||||
"moon__phase": {
|
||||
"new_moon": "New moon",
|
||||
"first_quarter": "First quarter",
|
||||
"full_moon": "Full moon",
|
||||
"last_quarter": "Last quarter"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Test translations
|
||||
|
||||
In order to test changes to translation files, the translation strings must be compiled into Home Assistant’s translation directories by running the following script:
|
||||
|
||||
```shell
|
||||
$ python3 -m script.translations develop
|
||||
```
|
||||
|
||||
### Introducing new strings
|
||||
|
||||
To introduce new strings, add them to `strings.json` or to a platform strings file. Try to use as many references to common strings as possible. Common strings live in `homeassistant/components/strings.json`. You can refer to those translations using references. For example:
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common.config_flow.abort.already_configured%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After the pull request with the strings file is merged into the `dev` branch, the strings will be automatically uploaded to Lokalise, where contributors can submit translations. The translated strings in Lokalise will be periodically pulled in to the core repository.
|
13
docs/internationalization/custom_integration.md
Normal file
13
docs/internationalization/custom_integration.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
title: "Custom Component Localization"
|
||||
---
|
||||
|
||||
## Translation Strings
|
||||
|
||||
Unlike localized strings merged in the `home-assistant` repository, custom components cannot take advantage of Lokalise for user-submitted translations. However, custom component authors can still include translations with their components. These will be read from the `translations` directory, adjacent to the component source. They are named `<platform name>.<language_code>.json`, e.g., for the German translation of a sensor `sensor.de.json`, unless the translation is for the custom component only, in which case the file is named `<language_code>.json` in the `translations` directory.
|
||||
|
||||
These files follow the same formatting as [backend translation string files](internationalization_backend_localization.md), but a copy will exist for each translated language.
|
||||
|
||||
The language codes follow the [BCP47](https://tools.ietf.org/html/bcp47) format. The [frontend translation files](https://github.com/home-assistant/home-assistant-polymer/tree/master/translations) can also be referred to if you are unsure of the correct language code to use.
|
||||
|
||||
To make sure that your translation files are correct, test with our integration validator Hassfest. [Set up instructions here.](https://developers.home-assistant.io/blog/2020/04/16/hassfest)
|
45
docs/translations.md
Normal file
45
docs/translations.md
Normal file
@ -0,0 +1,45 @@
|
||||
---
|
||||
title: "Translation"
|
||||
---
|
||||
|
||||
Translations for Home Assistant are managed through [Lokalise](https://lokalise.co/), an online translation management tool. Our translations are split between two projects, a backend project for platform-specific translations, and a frontend project for UI translations. Click the links below to join both projects! Even if your language is completely translated, extra proofreading is a big help! Please feel free to review the existing translations, and vote for alternatives that might be more appropriate.
|
||||
|
||||
- [Join the frontend translation team](https://lokalise.com/signup/3420425759f6d6d241f598.13594006/all/)
|
||||
- [Join the backend translation team](https://lokalise.com/signup/130246255a974bd3b5e8a1.51616605/all/)
|
||||
- [Join the iOS translation team](https://lokalise.com/signup/834452985a05254348aee2.46389241/all/)
|
||||
- [Join the Android translation team](https://lokalise.com/public/145814835dd655bc5ab0d0.36753359/)
|
||||
|
||||
For more information about the translation workflow, please see the [Lokalise translation workflow documents](https://docs.lokalise.co/category/iOzEuQPS53-for-team-leads-and-translators).
|
||||
|
||||
:::info
|
||||
The translation of the Home Assistant frontend is still a work in progress. More phrases will be available for translation soon.
|
||||
:::
|
||||
|
||||
## Translation placeholders
|
||||
|
||||
Some translation strings will contain special placeholders that will be replaced later. Placeholders shown in square brackets `[]` are [Lokalise key references](https://docs.lokalise.co/article/KO5SZWLLsy-key-referencing). These are primarily used to link translation strings that will be duplicated. Different languages may not have the same duplicates as English, and are welcome to link duplicate translations that are not linked in English. Placeholders shown in curly brackets `{}` are [translation arguments](https://formatjs.io/guides/message-syntax/) that will be replaced with a live value when Home Assistant is running. Any translation argument placeholders present in the original string must be included in the translated string. These may include special syntax for defining plurals or other replacement rules. The linked format.js guide explains the syntax for adding plural definitions and other rules.
|
||||
|
||||
## Rules
|
||||
1. Only native speakers should submit translations.
|
||||
2. Stick to [Material Design guidelines](https://material.io/guidelines/style/writing.html).
|
||||
3. Don't translate or change proper nouns like `Home Assistant`, `Hass.io` or `Hue`.
|
||||
4. For a region specific translation, keys that will be the same as the base translation should be filled with `[VOID]`. These will be replaced during our translation build process.
|
||||
5. Translations under the `state_badge` keys will be used for the notification badge display. These translations should be short enough to fit in the badge label without overflowing. This can be tested in the Home Assistant UI either by editing the label text with your browsers development tools, or by using the States tab of developer tools in the Home Assistant UI. In the UI, enter a new entity ID (`device_tracker.test`), and enter the text you want to test in state.
|
||||
6. If text will be duplicated across different translation keys, make use of the Lokalise key reference feature where possible. The base translation provides examples of this underneath the `states` translations. Please see the [Lokalise key referencing](https://docs.lokalise.com/en/articles/1400528-key-referencing) documentation for more details.
|
||||
|
||||
## Adding a new language
|
||||
If your language is not listed you can request it at [GitHub](https://github.com/home-assistant/home-assistant-polymer/issues/new). Please provide both the English name and the native name for your language. For example:
|
||||
```
|
||||
English Name: German
|
||||
Native Name: Deutsch
|
||||
```
|
||||
|
||||
:::info
|
||||
Region specific translations (`en-US`, `fr-CA`) will only be included if translations for that region need to differ from the base language translation.
|
||||
:::
|
||||
|
||||
### Maintainer steps to add a new language
|
||||
1. Language tags have to follow [BCP 47](https://tools.ietf.org/html/bcp47). A list of most language tags can be found here: [IANA sutbtag registry](http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry). Examples: `fr`, `fr-CA`, `zh-Hans`. Only include the country code if country specific overrides are being included, and the base language is already translated.
|
||||
2. Add the language tag and native name in `src/translations/translationMetadata.json`. Examples: "Français", "Français (CA)"
|
||||
3. Add the new language in Lokalize.
|
||||
Note: Sometimes you have to change the tag in Lokalise (Language -> Language settings -> custom ISO code).
|
@ -30,6 +30,7 @@ module.exports = {
|
||||
to: "docs/development_index",
|
||||
},
|
||||
{ to: "docs/frontend_index", label: "Frontend" },
|
||||
{ to: "docs/internationalization", label: "Internationalization" },
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -44,6 +45,7 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{ label: "Translations", to: "docs/translations", position: "left" },
|
||||
{
|
||||
label: "API",
|
||||
position: "left",
|
||||
|
12
sidebars.js
12
sidebars.js
@ -23,6 +23,12 @@ module.exports = {
|
||||
],
|
||||
},
|
||||
],
|
||||
Internationalization: [
|
||||
"internationalization",
|
||||
"internationalization/core",
|
||||
"internationalization/custom_integration",
|
||||
"translations",
|
||||
],
|
||||
Architecture: {
|
||||
Architecture: [
|
||||
"architecture_index",
|
||||
@ -122,12 +128,6 @@ module.exports = {
|
||||
},
|
||||
Misc: {
|
||||
Introduction: ["misc"],
|
||||
Internationalization: [
|
||||
"internationalization_index",
|
||||
"internationalization_backend_localization",
|
||||
"internationalization_custom_component_localization",
|
||||
"internationalization_translation",
|
||||
],
|
||||
Documentation: [
|
||||
"documentation_index",
|
||||
"documentation_standards",
|
||||
|
@ -11,3 +11,7 @@
|
||||
/docs/external_api_rest /docs/api/rest
|
||||
/docs/external_api_server_sent_events /docs/api/server-sent-events
|
||||
/docs/external_api_websocket /docs/api/websocket
|
||||
/docs/internationalization_backend_localization /docs/internationalization/core
|
||||
/docs/internationalization_custom_component_localization /docs/internationalization/custom_integration
|
||||
/docs/internationalization_index /docs/internationalization
|
||||
/docs/internationalization_translation /docs/translations
|
||||
|
Loading…
x
Reference in New Issue
Block a user