Skip to content

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

Open
CodingWithSaksham wants to merge 4 commits into
openwisp:masterfrom
CodingWithSaksham:issues/519-improve-i18n-coverage
Open

[chores] Improve i18n coverage for user-facing strings #519#539
CodingWithSaksham wants to merge 4 commits into
openwisp:masterfrom
CodingWithSaksham:issues/519-improve-i18n-coverage

Conversation

@CodingWithSaksham

@CodingWithSaksham CodingWithSaksham commented Jul 2, 2026

Copy link
Copy Markdown

Checklist

  • I have read the OpenWISP Contributing Guidelines.
  • I have manually tested the changes proposed in this pull request.
  • I have written new test cases for new code and/or updated existing tests for changes to existing code.
  • I have updated the documentation.

Reference to Existing Issue

Closes #519 .

Description of Changes

Fixed missing/broken translation coverage across openwisp_users (admin labels, login template, several admin messages and a model validation error that were silently untranslatable) and filled in the German ,Italian, Russian, and Slovenian translations for every newly extracted string.

NOTE

I used AI primarily to translate the text into different languages. Most of the translations were verified using Google Translate. However, some translations could not be verified because the strings contained variables and placeholders, and translating them directly with Google Translate produced incorrect or broken translations by altering those variables. In those cases, I relied on the AI generated translations.

Fixed missing/broken translation coverage across openwisp_users (admin labels, login template a model validation error that were silently untranslatable) and filled in the German ,Italian, Russian, and Slovenian translations for every newly extracted string.
Closes openwisp#519
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c0bd02ca-74c8-402b-b073-56af4779a8b3

📥 Commits

Reviewing files that changed from the base of the PR and between a935c94 and e5291e9.

📒 Files selected for processing (2)
  • openwisp_users/admin.py
  • openwisp_users/base/models.py
📜 Recent review details
⏰ Context from checks skipped due to timeout. (14)
  • GitHub Check: Python==3.10 | django~=5.0.0
  • GitHub Check: Python==3.12 | django~=5.0.0
  • GitHub Check: Python==3.10 | django~=5.2.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.12 | django~=5.2.0
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.13 | django~=5.2.0
  • GitHub Check: Python==3.11 | django~=5.0.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=5.1.0
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Mark user-facing strings for translation with Django i18n helpers in Django code
Place imports at the top of the file; only defer imports when necessary (e.g., Django model imports inside functions or methods where the app registry is not yet ready)
Avoid unnecessary blank lines inside function and method bodies
Write comments and docstrings only when they explain why code is shaped a certain way; place comments before the relevant code block instead of scattering them inside it

For Django pull requests, ensure all user-facing strings are marked as translatable using the Django i18n framework.

Files:

  • openwisp_users/base/models.py
  • openwisp_users/admin.py
🔇 Additional comments (2)
openwisp_users/admin.py (1)

111-111: LGTM!

Also applies to: 184-198, 277-281, 417-421, 499-509, 597-597, 666-676

openwisp_users/base/models.py (1)

501-504: LGTM!


📝 Walkthrough

Walkthrough

This PR expands i18n coverage by translating admin, model, mixin, and login-template strings. It replaces inline interpolation with named and plural-aware translation placeholders. German, Italian, Russian, and Slovenian catalogs for core and account functionality are regenerated with updated metadata, source references, translations, plural forms, and account email placeholder formatting.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: nemesifier


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Bug Fixes ❌ Error User-facing i18n paths changed, but I found no new regression test or locale-specific/Selenium coverage for them. Add a deterministic regression test that switches locale and asserts the translated UI strings render; for the admin UI, prefer a Selenium/browser test.
Changes ⚠️ Warning FAIL: The branch adds UI/admin i18n changes but the PR description has no screenshots, no test files were updated, and the docs edits only bump Django links rather than documenting changed behavior. Add screenshots/screen recordings, update or add tests covering the admin/model/template i18n changes, and revise docs only where behavior actually changed.
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title is descriptive, matches the i18n-focused changes, and references the linked issue.
Description check ✅ Passed The description includes the required checklist, issue reference, and change summary; only the screenshot section is missing.
Linked Issues check ✅ Passed The code and locale updates add translation markers and translations for the supported languages, matching #519's goals.
Out of Scope Changes check ✅ Passed The changes stay within the i18n scope and translation catalog updates without unrelated functionality changes.
Features ✅ Passed Not a feature request: the PR only updates i18n strings/translations and template wording, so feature-specific docs/screenshots/test requirements don’t apply.
General Rules ✅ Passed All touched UI strings use Django i18n helpers and the new locale entries are filled for de/it/ru/sl; no obvious security/perf issues.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coveralls

coveralls commented Jul 2, 2026

Copy link
Copy Markdown

Coverage Status

Coverage is 98.128%CodingWithSaksham:issues/519-improve-i18n-coverage into openwisp:master. No base build found for openwisp:master.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@openwisp_users/mixins.py`:
- Around line 63-75: The validation message in the organization-change check is
still built by splicing a translated verb fragment into a sentence, which should
be replaced with full plural-aware translations. Update the message construction
in the mixin method that raises ValidationError to use ngettext with complete
singular and plural sentence templates, and format only the named placeholders
such as count, object_label, and related_object_label. Remove the standalone
verb translation so the entire sentence is translated in context.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e50f2788-5d0a-49eb-a22b-9991fed86065

📥 Commits

Reviewing files that changed from the base of the PR and between f7bc7b1 and 0a8ca98.

📒 Files selected for processing (13)
  • openwisp_users/accounts/locale/de/LC_MESSAGES/django.po
  • openwisp_users/accounts/locale/it/LC_MESSAGES/django.po
  • openwisp_users/accounts/locale/ru/LC_MESSAGES/django.po
  • openwisp_users/accounts/locale/sl/LC_MESSAGES/django.po
  • openwisp_users/admin.py
  • openwisp_users/api/permissions.py
  • openwisp_users/base/models.py
  • openwisp_users/locale/de/LC_MESSAGES/django.po
  • openwisp_users/locale/it/LC_MESSAGES/django.po
  • openwisp_users/locale/ru/LC_MESSAGES/django.po
  • openwisp_users/locale/sl/LC_MESSAGES/django.po
  • openwisp_users/mixins.py
  • openwisp_users/templates/admin/openwisp_users/login.html
📜 Review details
⏰ Context from checks skipped due to timeout. (14)
  • GitHub Check: Python==3.13 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=5.2.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=5.0.0
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=5.2.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=5.0.0
  • GitHub Check: Python==3.10 | django~=5.0.0
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (Custom checks)

For Django pull requests, ensure all user-facing strings are marked as translatable using the Django i18n framework (django.utils.translation.gettext, gettext_lazy, or ugettext aliases)

**/*.py: Mark user-facing strings for translation with Django i18n helpers in Django code
Place imports at the top of the file; only defer imports when necessary (e.g., Django model imports inside functions or methods where the app registry is not yet ready)
Avoid unnecessary blank lines inside function and method bodies
Write comments and docstrings only when they explain why code is shaped a certain way; place comments before the relevant code block instead of scattering them inside it

Files:

  • openwisp_users/api/permissions.py
  • openwisp_users/mixins.py
  • openwisp_users/base/models.py
  • openwisp_users/admin.py
🪛 HTMLHint (1.9.2)
openwisp_users/templates/admin/openwisp_users/login.html

[warning] 47-47: No matching [ label ] tag found.

(input-requires-label)

🔇 Additional comments (18)
openwisp_users/locale/de/LC_MESSAGES/django.po (1)

140-148: 📐 Maintainability & Code Quality | ⚡ Quick win

Fix the plural agreement in this translation.

permission_classes reads as plural here, so wurde is incorrect. Use wurden or rephrase the sentence so the admin error reads naturally.

Suggested fix
- "permission_classes der View wurde nicht korrekt implementiert. Bitte "
+ "permission_classes der View wurden nicht korrekt implementiert. Bitte "
openwisp_users/locale/it/LC_MESSAGES/django.po (1)

142-150: 📐 Maintainability & Code Quality | ⚡ Quick win

Fix the verb agreement in this translation.

permission_classes is plural in context, so non implementata should be non implementate.

Suggested fix
- "permission_classes della view non implementata correttamente. Utilizza una "
+ "permission_classes della view non implementate correttamente. Utilizza una "
openwisp_users/locale/ru/LC_MESSAGES/django.po (1)

141-149: 📐 Maintainability & Code Quality | ⚡ Quick win

Rephrase this error message for grammar.

permission_classes представления реализовано некорректно is not natural Russian. Please rewrite the sentence so the technical term stays intact but the message reads correctly.

Suggested fix
- "permission_classes представления реализовано некорректно. Используйте один "
+ "Свойство permission_classes у представления реализовано некорректно. Используйте один "
openwisp_users/locale/sl/LC_MESSAGES/django.po (1)

134-142: 📐 Maintainability & Code Quality | ⚡ Quick win

Fix the broken grammar in this translation.

permission_classes poglede ni pravilno implementiran is not grammatical Slovenian. Please rewrite the full sentence before shipping.

Suggested fix
- "permission_classes poglede ni pravilno implementiran. Uporabite enega od "
+ "permission_classes pogleda niso pravilno implementirane. Uporabite enega od "
openwisp_users/accounts/locale/de/LC_MESSAGES/django.po (1)

9-18: LGTM!

Also applies to: 45-56, 57-73, 74-213

openwisp_users/accounts/locale/it/LC_MESSAGES/django.po (1)

9-16: LGTM!

Also applies to: 44-63, 72-80, 122-144, 154-207

openwisp_users/accounts/locale/ru/LC_MESSAGES/django.po (1)

8-19: LGTM!

Also applies to: 30-37, 49-102, 112-220

openwisp_users/accounts/locale/sl/LC_MESSAGES/django.po (1)

9-19: LGTM!

Also applies to: 51-76, 86-222

openwisp_users/templates/admin/openwisp_users/login.html (3)

44-48: HTMLHint "missing label" warning on the submit input is a pre-existing false positive, not introduced by this change.

Submit inputs get their accessible name from the value attribute; no <label> association is required here. No action needed for this i18n change.

Source: Linters/SAST tools


7-7: LGTM! This mirrors Django's own admin idiom for singular/plural error banners.


23-26: LGTM! blocktrans trimmed correctly wraps the full sentence with the {{ username }} variable inline.

openwisp_users/admin.py (5)

183-197: LGTM!


266-282: LGTM! This mirrors Django's own admin pattern of using gettext with model_ngettext for the pluralized noun while keeping a single sentence template.


399-422: LGTM!


489-509: LGTM!


642-675: LGTM!

openwisp_users/base/models.py (1)

492-504: LGTM! Named-placeholder formatting is applied correctly and matches the test expectation for the owner-downgrade error.

openwisp_users/api/permissions.py (1)

46-53: LGTM!

Comment thread openwisp_users/mixins.py Outdated
Comment thread openwisp_users/api/permissions.py Outdated
@coderabbitai coderabbitai Bot removed the enhancement label Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[chores] Improve i18n coverage for user-facing strings

3 participants