SKILL.md
SKILL.mdBrowse 20 files
2,205 tokens
9,465 bytes
Token encoding: o200k_base
Snapshot 2aca1aa
1---2name: airflow-translations3description: >4 Add or update translations for the Apache Airflow UI.5 Guides through setting up locales, scaffolding translation files, translating6 with locale-specific guidelines, and validating results. Use when working with7 i18n tasks in airflow-core/src/airflow/ui/public/i18n/locales/.8license: Apache-2.09---10<!-- SPDX-License-Identifier: Apache-2.011 https://www.apache.org/licenses/LICENSE-2.0 -->12 13# Airflow Translations14 15## Determining the Task16 17Translation work falls into one of two categories depending on whether the18target locale already exists. Check if a directory for the locale exists under19`airflow-core/src/airflow/ui/public/i18n/locales/<locale>/`. If it does, skip20ahead to **Updating an Existing Translation**. If not, start with **Adding a Translation** below.21 22---23 24## Adding a Translation25 26When adding a translation, some configuration files need to be updated before translation work can begin.27 28### Setting up the locale29 30First, create the locale directory:31 32```33mkdir -p airflow-core/src/airflow/ui/public/i18n/locales/<locale>/34```35 36Then update the following configuration files, keeping the existing alphabetical37ordering in each file:38 39**`airflow-core/src/airflow/ui/src/i18n/config.ts`**: add the locale to the40`supportedLanguages` array:41 42```ts43{ code: "<locale>", name: "<native name>" },44```45 46**`dev/breeze/src/airflow_breeze/commands/ui_commands.py`**: add the plural47suffixes for the language to the `PLURAL_SUFFIXES` dict. Check the i18next48plural rules for the language at <https://jsfiddle.net/6bpxsgd4> to determine49which suffixes are needed:50 51```52"<locale>": ["<suffixes>"],53```54 55**`.github/boring-cyborg.yml`**: under `labelPRBasedOnFilePath`, add:56 57```yaml58translation:<locale>:59 - airflow-core/src/airflow/ui/public/i18n/locales/<locale>/*60```61 62### Scaffolding the translation files63 64Once the configuration is in place, run the breeze command to copy every65English namespace file into the new locale directory. This populates each key66with a `TODO: translate:` stub:67 68```bash69breeze ui check-translation-completeness --language <locale> --add-missing70```71 72The generated files will look like this:73 74```json75{76 "allRuns": "TODO: translate: All Runs",77 "blockingDeps": {78 "dependency": "TODO: translate: Dependency",79 "reason": "TODO: translate: Reason"80 }81}82```83 84### Translating85 86With the scaffolded files in place, read the locale-specific guideline for the87target language (see the table under **Locale-Specific Guidelines** below). If88one exists, it contains the glossary, tone rules, and formatting conventions89that must be followed. If no locale-specific guideline exists yet, follow the90translation rules described later in this document.91 92Replace every `TODO: translate: <English terminology>` entry, including the prefix,93with the translated string.94 95After all entries are translated, continue to **Validation** below.96 97---98 99## Updating an Existing Translation100 101When a locale already exists and you need to fill translation gaps, revise102existing translations, or remove stale keys, start by reading the103locale-specific guideline for the language (see the table under104**Locale-Specific Guidelines** below). This establishes the glossary and105formatting rules to follow.106 107Next, read the locale's existing JSON files under108`airflow-core/src/airflow/ui/public/i18n/locales/<locale>/` to learn the109terminology already in use. Consistency with established translations is110critical. If a term has been translated a certain way, reuse that exact111translation.112 113Then check the current state of completeness:114 115```bash116breeze ui check-translation-completeness --language <locale>117```118 119If there are **missing** keys, scaffold them with `TODO: translate:` stubs:120 121```bash122breeze ui check-translation-completeness --language <locale> --add-missing123```124 125If there are **unused** keys — keys that are not required, meaning they are126absent from the English locale or are plural suffixes this language does not127need — remove them:128 129```bash130breeze ui check-translation-completeness --language <locale> --remove-unused131```132 133Now translate the `TODO: translate:` entries following the locale-specific134guideline, then continue to **Validation** below.135 136---137 138## Validation139 140After completing translations, run these checks:141 142Check completeness. The output table should show 0 missing, 0 TODOs, 0 unused,143and 100% coverage:144 145```bash146breeze ui check-translation-completeness --language <locale>147```148 149Run pre-commit hooks to fix formatting, licenses, and linting issues:150 151```bash152prek run --from-ref main --hook-stage pre-commit153```154 155---156 157## General Translation Rules158 159The following rules apply globally. If the locale-specific guideline for a160language states differently, follow the locale-specific guideline.161 162### Terms Kept in English163 164The terms below should remain in English by default. Locale-specific guidelines165may override individual entries where an established local convention exists:166 167| Term | Reason |168| ------------------------ | -------------------------------------------- |169| `Airflow` | Product name |170| `Dag` / `Dags` | Airflow convention; always `Dag`, never `DAG`|171| `XCom` / `XComs` | Airflow cross-communication mechanism name |172| `Provider` / `Providers` | Airflow extension package name |173| `REST API` | Standard technical term |174| `JSON` | Standard technical format name |175| `ID` | Universal abbreviation |176| `PID` | Unix process identifier |177| `UTC` | Time standard |178| `Schema` | Database term |179 180### Variables and Placeholders181 182Translation strings use `{{variable}}` interpolation (i18next format).183Never translate or remove variable names inside `{{…}}`. Placeholders may be184reordered as needed for natural word order, but the exact variable casing must185be preserved (e.g., `{{dagDisplayName}}`).186 187### Plural Forms188 189Airflow uses i18next plural suffixes (`_one`, `_other`, and optionally `_zero`,190`_two`, `_few`, `_many`). Provide translations for all plural suffixes that the191language requires — the locale-specific guideline specifies which ones. If no192locale guideline exists, check the i18next plural rules at193<https://jsfiddle.net/6bpxsgd4> and provide at minimum `_one` and `_other`.194 195### Hotkeys196 197Hotkey values (e.g., `"hotkey": "e"`) are literal key bindings and should198**not** be translated unless the locale-specific guideline says otherwise.199 200---201 202## Translation File Structure203 204All translation files are JSON files located at:205 206```207airflow-core/src/airflow/ui/public/i18n/locales/<locale-name>/208```209 210Each locale directory contains namespace JSON files that mirror the English211locale (`en/`). The English locale is the **default locale** and the primary212source for all translations. The current namespace files are:213 214<!-- START namespace-files, please keep comment here to allow auto update -->215`admin.json`, `assets.json`, `browse.json`, `common.json`, `components.json`, `dag.json`, `dags.json`, `dashboard.json`, `hitl.json`, `tasks.json`216<!-- END namespace-files, please keep comment here to allow auto update -->217 218---219 220## Locale-Specific Guidelines221 222Before translating, read the locale-specific guideline file for the target223language. These contain glossaries, tone rules, and formatting conventions224tailored to each language. If a locale-specific guideline states differently225from a global rule in this document, follow the locale-specific guideline.226 227| Locale Code | Language | Guideline File |228| ----------- | ----------------------- | ------------------------------- |229| `ar` | Arabic | [locales/ar.md](locales/ar.md) |230| `ca` | Catalan | [locales/ca.md](locales/ca.md) |231| `de` | German | [locales/de.md](locales/de.md) |232| `el` | Greek | [locales/el.md](locales/el.md) |233| `es` | Spanish | [locales/es.md](locales/es.md) |234| `fr` | French | [locales/fr.md](locales/fr.md) |235| `he` | Hebrew | [locales/he.md](locales/he.md) |236| `hi` | Hindi | [locales/hi.md](locales/hi.md) |237| `hu` | Hungarian | [locales/hu.md](locales/hu.md) |238| `it` | Italian | [locales/it.md](locales/it.md) |239| `ja` | Japanese | [locales/ja.md](locales/ja.md) |240| `ko` | Korean | [locales/ko.md](locales/ko.md) |241| `nl` | Dutch | [locales/nl.md](locales/nl.md) |242| `pl` | Polish | [locales/pl.md](locales/pl.md) |243| `pt` | Portuguese | [locales/pt.md](locales/pt.md) |244| `th` | Thai | [locales/th.md](locales/th.md) |245| `tr` | Turkish | [locales/tr.md](locales/tr.md) |246| `zh-CN` | Simplified Chinese | [locales/zh-CN.md](locales/zh-CN.md) |247| `zh-TW` | Traditional Chinese | [locales/zh-TW.md](locales/zh-TW.md) |248 249If the target locale file does not yet exist, follow only the global rules in250this document.251 Discovery context
Discovered by repository scan. No exact path reference found in the snapshot’s root AGENTS.md.
