5.1 KiB
Translations Guide (i18n)
This document explains how to:
- add a new language
- edit an existing language
- update translations when new text is added in the app
The app uses JSON-based translations loaded from:
- resources/translations/
1. Translation System Overview
Main components:
- src/webdrop_bridge/utils/i18n.py
- Loads language JSON files
- Provides tr("key", **kwargs)
- Falls back to English if a key is missing
- src/webdrop_bridge/main.py
- Initializes i18n at app startup
- src/webdrop_bridge/config.py
- Stores selected language in config (language field)
- src/webdrop_bridge/ui/settings_dialog.py
- Language selector in Settings -> General
Current language files:
- resources/translations/en.json
- resources/translations/de.json
- resources/translations/fr.json
- resources/translations/it.json
- resources/translations/ru.json
- resources/translations/zh.json
2. Add a New Language
Example: add Spanish (es).
-
Create a new file:
- resources/translations/es.json
-
Copy the full structure from English:
- Copy resources/translations/en.json to resources/translations/es.json
-
Translate all values in es.json:
- Keep all keys exactly the same
- Only change text values
- Keep placeholders unchanged, for example:
- {name}
- {version}
- {error}
-
Add language display name in i18n helper:
- Edit src/webdrop_bridge/utils/i18n.py
- In Translator.BUILTIN_LANGUAGES add:
- "es": "Español"
-
Start app and test:
- Choose language in Settings -> General
- Restart app when prompted
- Verify tooltips, dialogs, status texts, settings labels, update dialogs
3. Edit an Existing Language
-
Open the language file, for example:
- resources/translations/de.json
-
Update only text values.
-
Do not:
- remove keys
- rename keys
- change placeholder names
-
Validate JSON formatting:
- Must be valid JSON
- Keep UTF-8 encoding
-
Test in app:
- Select language in Settings
- Restart and verify changed text appears
4. When New Text Is Added in the App
Whenever new UI text is introduced in code, follow this process.
Step A: Add a new translation key in code
Instead of hardcoded text, use tr("...") with a key.
Example:
- Before: QLabel("Check for Updates")
- After: QLabel(tr("toolbar.tooltip.check_updates"))
If dynamic text is needed:
- tr("update.status.available", version=release.version)
Step B: Add the key to English first
-
Add the new key in:
- resources/translations/en.json
-
Use clear key naming by area, for example:
- toolbar.tooltip.*
- dialog.*
- settings.*
- update.*
- status.*
- worker.*
Step C: Add the same key to all other language files
Update each file in resources/translations:
- de.json
- fr.json
- it.json
- ru.json
- zh.json
- and any new language file
If translation is not ready yet, copy English temporarily (better than missing key text in UI).
Step D: Test fallback and real translations
- Run app in English and verify new text.
- Run app in other languages and verify translated text.
- Confirm no raw key appears in UI (for example: dialog.my_new_key).
5. Placeholder Rules
Placeholders must match exactly between code and translation values.
If code uses:
- tr("status.opened", name=file_name)
Then translation must contain:
- "status.opened": "Opened: {name}"
Common mistakes:
- wrong placeholder name ({filename} vs {name})
- missing placeholder
- extra placeholder not passed by code
6. Recommended Workflow for Translation Updates
- Implement UI text with tr("key") in code.
- Add key to en.json.
- Copy key to all language files.
- Run tests.
- Smoke test manually in app.
Useful test command:
- python -m pytest tests/unit/test_i18n.py -q
Recommended additional checks when UI changed:
- python -m pytest tests/unit/test_settings_dialog.py tests/unit/test_update_manager_ui.py tests/unit/test_startup_check.py -q
7. Troubleshooting
Problem: Language changed in settings but UI language did not change
Expected behavior:
- language is applied after restart
Check:
- language value saved in config file
- restart prompt appears after changing language
- selected language JSON file exists and is valid
Problem: UI shows translation key text instead of real text
Example shown in UI:
- settings.title
Cause:
- key missing in selected language and missing in en.json fallback
Fix:
- add key to en.json
- add key to selected language file
Problem: Text formatting errors
Cause:
- placeholder mismatch
Fix:
- compare tr(...) arguments in code with placeholders in translation string
8. Best Practices
- Keep en.json as complete source of truth.
- Keep key names stable once released.
- Group keys by feature area.
- Prefer short, user-friendly text in UI.
- Use formal, consistent tone per language.
- Review non-Latin languages (RU/ZH) with a native speaker when possible.
9. Quick Checklist
When adding new text:
- Add tr("new.key") in code
- Add key in en.json
- Add key in all other language files
- Verify placeholders
- Run i18n and impacted UI tests
- Manual in-app check with at least one non-English language