Opened 10 years ago
Closed 10 years ago
#25297 closed Bug (fixed)
makemessages doesn't detect the context of {% trans %} strings with a filter
| Reported by: | Alexandre Pocquet | Owned by: | nobody |
|---|---|---|---|
| Component: | Internationalization | Version: | 1.8 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Ready for checkin | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | yes |
| Easy pickings: | no | UI/UX: | no |
Description
The following:
{% trans 'inactive'|upper context 'plural' %}
Is (incorrectly) extracted as:
msgid "inactive" msgstr ""
Whereas the following:
{% trans 'inactive' context 'plural' %}
Is (correctly) extracted as:
msgctxt "plural" msgid "inactive" msgstr ""
Translating the former has no effect on the template rendering, as it lacks the context.
Translating the latter makes the translation to be correctly rendered, both without the filter, and with the filter if added after makemessages was called.
I think this is a bug with the makemessages command.
Environnement:
Linux Mint Debian Edition
CPython 3.4.2
Django 1.8.3
GNU gettext 0.19.3
Command used:
./manage.py makemessages -v 1 -l fr
./manage.py compilemessages
Change History (8)
comment:1 by , 10 years ago
| Summary: | The makemessages command does not detect the context of {% trans %} templatetags with filter → The makemessages command does not detect the context of {% trans %} templatetags with a filter |
|---|
comment:2 by , 10 years ago
| Summary: | The makemessages command does not detect the context of {% trans %} templatetags with a filter → makemessages doesn't detect the context of {% trans %} strings with a filter |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
| Type: | Uncategorized → Bug |
comment:3 by , 10 years ago
I think the problem may come from the inline_re definition in django.utils.translation.trans_real . It it used by the templatize function, which it itself called from the commandline handler.
Current:
inline_re = re.compile(r"""^\s*trans\s+((?:"[^"]*?")|(?:'[^']*?'))(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?\s*""")
Possible correction:
inline_re = re.compile(r"""^\s*trans\s+((?:"[^"]*?")|(?:'[^']*?'))(?:\s*\|\s*[^\s:]+(?::(?:[^\s'":]+|(?:"[^"]*?")|(?:'[^']*?')))?)*(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?\s*""")
The (?:\s*\|\s*[^\s]+(?::(?:\s+|(?:"[^"]*?")|(?:'[^']*?'))?))* regex should catch and throw away any filter. I may be wrong, I don't know the precise syntax of a filter name.
The first part is quite simple and matches a | followed by a filter name. The second part (starting with ?::) is more complex because it must match filter arguments, including string literals.
Test here.
comment:4 by , 10 years ago
| Has patch: | set |
|---|---|
| Patch needs improvement: | set |
PR (but has a test failure).
comment:5 by , 10 years ago
| Patch needs improvement: | unset |
|---|
comment:6 by , 10 years ago
| Patch needs improvement: | set |
|---|
Left some comments for improvement on the pull request.
comment:7 by , 10 years ago
| Triage Stage: | Accepted → Ready for checkin |
|---|
If this cannot be made to work for some reason, documenting the restriction may be helpful.