Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Translation support (I18n) #240

Merged
merged 18 commits into from
Feb 25, 2025
Merged

Conversation

flattermann
Copy link
Collaborator

Added support for translations via text files in /i18n/.

Each line in the translation files is a simple key=value pair.

We parse the files in this order:

  1. Load default language file (en.txt)
  2. Load selected language file (e.g. de.txt), use the default language as fallback
  3. For every widget, load default language file (en.widgetname.txt)
  4. For every widget, load selected language file (e.g. de.widgetname.txt), use the default language as fallback

We can use I18n::get("key") to use the i18n strings.

This also supports parameters, e.g. I18n::get("version", "2.0").

I would recommend for the widget specific files to use a prefix for each key, e.g. parqet.name=Parqet to avoid name clashes.

See also #238

Introduced an i18n system for localizing app text using key-value language files. Added `I18n.h` and `I18n.cpp` to manage translations, integrated i18n into welcome screens, and updated `MainHelper` to facilitate setup. Created a sample English language file (`i18n/en.txt`).
Updated the scripts to include wildcard file matching using `glob` for greater flexibility in file selection. Refactored and fixed formatting inconsistencies for improved readability. These changes streamline file embedding and copying processes in build workflows.
Introduced dynamic widget-specific translations and centralized language management in I18n. Added helper methods in WidgetSet for widget retrieval and improved iteration logic. This lays groundwork for better localization support and improves code consistency.
Move the I18N_DIR macro from MainHelper.h to I18n.h for better encapsulation and logical grouping of localization-related definitions. Also, remove an unnecessary include of MainHelper.h in I18n.cpp.
Removed redundant empty name check and clarified translation loading process in `WidgetSet`. Added localization entry for "Parqet" and improved robustness of `loadExtraTranslations` to handle empty suffixes.
Updated I18n system to handle a default language fallback when loading translations, ensuring robust behavior when specific language files are unavailable. Renamed parameters and improved clarity in translation loading logic for better maintainability.
Introduce language selection using a dropdown in the configuration settings, replacing hardcoded default handling. Added support for managing language IDs, retrieving available languages, and loading translations dynamically based on the selected language.
    Adjusted the decrement logic in WidgetSet::prev() to prevent accessing invalid widget indices. Ensures proper wrapping behavior when navigating to the previous widget in the circular widget list.
Replaced hardcoded "Loading data:" text in WidgetSet with a translatable string using the i18n system. Added the "loading_data" key to English and German translation files to support localization. This improves maintainability and enables multi-language support.
Updated I18n to use `const char*` for translations to reduce memory usage and added proper cleanup via `clearTranslations()`. Implemented dynamic loading of widget-specific translations and updated ParqetWidget to leverage these changes. Adjusted related files and language resources accordingly.
Replaced hardcoded strings with the newly implemented `i18n` function, centralizing translation handling and improving maintainability. Updated translation files (en/de) with additional keys for widget configuration options and labels. This ensures consistency and simplifies future localization efforts.
Updated i18n keys for consistency and improved translation handling. Added logging for missing and found translations in `I18n::get`. Simplified configuration translations using the `i18n` helper method for clarity and maintainability.
Standardize and localize configuration text by replacing raw strings with i18n keys in `ParqetWidget.cpp`. Added missing translations for new i18n keys in German and English localization files. Improved consistency and clarity in user-facing configuration labels.
@flattermann
Copy link
Collaborator Author

I rebased this branch to the current dev branch.

The translations work, but there are some limitations with my current approach:

On startup, I'm loading the translation string in a map<String, const char*>.
That means that the translated strings are stored in RAM. For the strings in this PR, this will consume ~3kB of RAM.
If we convert all WebPortal config strings to i18n, this will probably be around 8-10kB of RAM.

I don't really like that (RAM is precious!), that's why I'd like to try a different approach before merging this PR:

I'll try to put the translations in the source code instead of files on the LittleFS. This will probably allow us to store the translations in PROGMEM instead of RAM. But we lose the ability to download/edit/upload the translations without recompilation.

@flattermann flattermann added the DO NOT MERGE Work in progress not ready to be considered for merging label Feb 25, 2025
Replaced hardcoded strings with i18n keys across various modules to improve translations consistency and maintainability. Introduced dedicated translation files for better organization, including new headers in specific widgets like `ParqetWidget`. Optimized i18n function usage in configuration settings and removed outdated translation management logic.
Updated German translations to improve clarity and consistency. Simplified English rotation descriptions to remove redundant "clockwise" term. French translations remain unchanged.
Removed unused `getAllWidgets` and `getWidgetCount` methods from `WidgetSet`. Cleaned up redundant includes in `MainHelper.h` and adjusted related files for consistency. Minor update to use `DEFAULT_LANGUAGE` instead of a hardcoded value.
@flattermann flattermann removed the DO NOT MERGE Work in progress not ready to be considered for merging label Feb 25, 2025
@flattermann
Copy link
Collaborator Author

Ok, I switched to code based translations now.

We have one file for general translations: src/core/i18n/Translations.cpp and each widget can also have their own translations, e.g. src/widgets/parqetwidget/ParqetTranslations.cpp.

See the two files above for examples.

I've included translations for EN, DE, FR for some WebPortal config options (Sections "General", "TFT Settings" and "ParqetWidget").

FR definitely needs checking, because it's an automated translation.

@brett-dot-tech brett-dot-tech merged commit 28963a8 into brettdottech:dev Feb 25, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants