Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#30081 closed New feature (wontfix)

Translation with context - makemessages doesn't recognize the context

Reported by: אורי Owned by: nobody
Component: Core (Management commands) Version: 1.11
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by אורי)

We are using Django for Speedy Net and Speedy Match (currently Django 1.11.18, we can't upgrade to a newer version of Django because of one of our requirements, django-modeltranslation). I have a problem with translating strings with context. We use context mainly for translating strings differently depending on the user's gender, which translates differently in languages such as Hebrew, although the English strings are the same. For example, I have this code:

raise ValidationError(pgettext_lazy(context=self.instance.get_gender(), message="You can't change your username."))

(you can see it on https://github.com/speedy-net/speedy-net/blob/staging/speedy/core/accounts/forms.py)

The problem is that manage.py makemessages doesn't recognize the context here. A workaround we found is to include this text manually in files we don't use at all, such as __translations.py or __translations.html (you can see them on https://github.com/speedy-net/speedy-net/blob/staging/speedy/core/base/__translations.py and https://github.com/speedy-net/speedy-net/blob/staging/speedy/core/templates/__translations.html respectively), and there we can include the same strings with context:

Either:

pgettext_lazy(context="female", message="You can't change your username.")
pgettext_lazy(context="male", message="You can't change your username.")
pgettext_lazy(context="other", message="You can't change your username.")

Or:

{% trans "You can't change your username." context 'female' %}
{% trans "You can't change your username." context 'male' %}
{% trans "You can't change your username." context 'other' %}

But this is a lot of work and we have each string 4 times in our code (not including translations), and it's very difficult to maintain such a code. And as I said, these files are not used at all, they are only for ./make_all_messages.sh to work properly. So my question is - is there a way to pass all the possible contexts as a list to manage.py makemessages? For example add another argument to pgettext_lazy or add a specific comment which will be read by manage.py makemessages? I checked and currently we use translation with context about 100 times in this project, and it would be a lot of work to generate all this code (100 * 3 times) just for manage.py makemessages to work.

By the way, the method get_gender() always returns one of these strings: "female", "male" or "other". There is also another method, get_match_gender(), which returns the same values.

Is it possible to define the context "other" as default, so if a different context (or none) is passed and there is no translation with the given context, "other" will be used?

Change History (4)

comment:1 by Claude Paroz, 5 years ago

Resolution: wontfix
Status: newclosed

I understand this might be heavy to manage, but we are limited by the gettext approach which collect strings by static code analysis. Unfortunately, I don't see what we can do to change that. At your level, you might centralized strings in a single file and then use a custom function to retrieve them. This *could* be a little more easier to manage (single file to update), but you would still have to duplicate the strings for each context so as gettext can collect them.

If you can give us some proof of concept code to improve your use case, feel free to reopen it.

comment:2 by אורי, 5 years ago

You can see the relevant files on the following directories:

https://github.com/speedy-net/speedy-net/tree/staging/speedy/core/__translations
https://github.com/speedy-net/speedy-net/tree/staging/speedy/match/__translations

https://github.com/speedy-net/speedy-net/tree/staging/speedy/core/locale
https://github.com/speedy-net/speedy-net/tree/staging/speedy/match/locale

You can see that some of the Hebrew translations there are different per context (gender). For example the translations of "You haven't confirmed your email address. Please check your inbox." or "Unlike". And also English translations, for example "but you can visit his/her Speedy Net profile. " (but we don't have to use translations with context here, we can just use 3 different strings. It's just easier to use translations because we already have contexts).

Last edited 5 years ago by אורי (previous) (diff)

comment:3 by Claude Paroz, 5 years ago

Oh, looks like you already have a (almost?) working setup, then. I guess you could use a pgettext alias in the "real" code, because you don't need gettext extracting your strings in the code.
Feel free to poke me privately if you need some counsel, but unfortunately I still don't see a common enough use case here to warrant a modification in Django itself.

comment:4 by אורי, 5 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top