Background
OpenWISP aims to provide a fully localized user experience across all
supported languages. Some user-facing strings are currently not properly
internationalized, and some newly introduced strings may also be missing
translations in the existing .po files.
This leads to incomplete localization where parts of the UI remain
untranslated.
Goal
Ensure that:
- All user-facing strings are marked for translation in the codebase
- All marked strings have corresponding translations in supported
languages
Supported languages:
- Italian (
it)
- German (
de)
- Slovenian (
sl)
- Russian (
ru)
What needs to be done
1. Identify missing translation markers in code
Search for user-facing strings that are not wrapped using Django i18n
utilities.
Python:
_()
gettext_lazy()
ngettext()
Templates:
{% trans %}
{% blocktrans %}
Focus on:
- UI labels
- Form validation messages
- Error messages
- Help text shown to users
- Admin-visible strings
2. Mark strings for translation
Wrap all missing strings using appropriate Django translation functions.
Example (Python):
from django.utils.translation import gettext_lazy as _
# before
default_error = "Invalid password"
# after
default_error = _("Invalid password")
Example (template):
{% trans "Save changes" %}
{% blocktrans %}Welcome {{ user }}{% endblocktrans %}
3. Extract updated message catalogs
After code changes, update translation files:
python manage.py makemessages -l it -l de -l sl -l ru
This ensures all new translatable strings are reflected in .po files.
4. Add missing translations
Update the following files:
locale/<lang>/LC_MESSAGES/django.po
For each newly introduced msgid, ensure a proper translation is
provided.
Requirements:
- All new strings added via
makemessages must be translated
- Do not leave
msgstr "" for new entries
- Preserve formatting placeholders (
%s, %(name)s, {}, etc.)
- Ensure consistency of terminology across the application
5. Compile translations
Run:
python manage.py compilemessages
This compiles the .po files into .mo files used at runtime.
Validation criteria
- All user-facing strings in Python and templates are marked for
translation
- No missing i18n wrappers remain in UI-facing code
makemessages runs cleanly and captures all new strings
- All supported language files include translations for new entries
compilemessages succeeds without errors
- UI shows correct translations when switching languages
Avoid
- Refactoring unrelated code
- Changing application logic
- Wrapping internal-only logs or debug statements
- Double-wrapping already translated strings
Notes for contributors
If unsure whether a string is user-facing, assume it is if it appears
in:
- UI
- Forms
- Validation errors
- Admin interface
- API responses consumed by frontend
When in doubt, prefer marking strings for translation.
Background
OpenWISP aims to provide a fully localized user experience across all
supported languages. Some user-facing strings are currently not properly
internationalized, and some newly introduced strings may also be missing
translations in the existing
.pofiles.This leads to incomplete localization where parts of the UI remain
untranslated.
Goal
Ensure that:
languages
Supported languages:
it)de)sl)ru)What needs to be done
1. Identify missing translation markers in code
Search for user-facing strings that are not wrapped using Django i18n
utilities.
Python:
_()gettext_lazy()ngettext()Templates:
{% trans %}{% blocktrans %}Focus on:
2. Mark strings for translation
Wrap all missing strings using appropriate Django translation functions.
Example (Python):
Example (template):
3. Extract updated message catalogs
After code changes, update translation files:
This ensures all new translatable strings are reflected in
.pofiles.4. Add missing translations
Update the following files:
For each newly introduced
msgid, ensure a proper translation isprovided.
Requirements:
makemessagesmust be translatedmsgstr ""for new entries%s,%(name)s,{}, etc.)5. Compile translations
Run:
This compiles the
.pofiles into.mofiles used at runtime.Validation criteria
translation
makemessagesruns cleanly and captures all new stringscompilemessagessucceeds without errorsAvoid
Notes for contributors
If unsure whether a string is user-facing, assume it is if it appears
in:
When in doubt, prefer marking strings for translation.