Skip to content

[chores] Improve i18n coverage for user-facing strings #519

@pandafy

Description

@pandafy

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:

  1. All user-facing strings are marked for translation in the codebase
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No fields configured for Task.

    Projects

    Status
    To do (general)

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions