# 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). 1. Create a new file: - resources/translations/es.json 2. Copy the full structure from English: - Copy resources/translations/en.json to resources/translations/es.json 3. Translate all values in es.json: - Keep all keys exactly the same - Only change text values - Keep placeholders unchanged, for example: - {name} - {version} - {error} 4. Add language display name in i18n helper: - Edit src/webdrop_bridge/utils/i18n.py - In Translator.BUILTIN_LANGUAGES add: - "es": "EspaƱol" 5. 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 1. Open the language file, for example: - resources/translations/de.json 2. Update only text values. 3. Do not: - remove keys - rename keys - change placeholder names 4. Validate JSON formatting: - Must be valid JSON - Keep UTF-8 encoding 5. 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 1. Add the new key in: - resources/translations/en.json 2. 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 1. Run app in English and verify new text. 2. Run app in other languages and verify translated text. 3. 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 1. Implement UI text with tr("key") in code. 2. Add key to en.json. 3. Copy key to all language files. 4. Run tests. 5. 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