4

As mentioned in this section of Translation | Django documentation, the function ugettext_noop is a utility function for internationalization:

ugettext_noop(message)

Marks strings for translation but doesn’t translate them now. This can be used to store strings in global variables that should stay in the base language (because they might be used externally) and will be translated later.

Also, this answer provides an example of its usage:

import logging
from django.http import HttpResponse
from django.utils.translation import ugettext as _, ugettext_noop as _noop

def view(request):
    msg = _noop("An error has occurred")
    logging.error(msg)
    return HttpResponse(_(msg))

Despite these docs, I still don't understand why should I mark a string as extractable for translation. To me it seems that ugettext_noop is nothing but a reminder, and even so, what's the purpose of reminding programmers that some strings (msg in this case) are to be translated later?

Community
  • 1
  • 1
nalzok
  • 14,965
  • 21
  • 72
  • 139

1 Answers1

10

Once I have a task to make event log with storing its messages in database. It had to support i18n. So firstly I marked all event log messages with ugettext_noop function. In this case they were not translated before adding to database. But at the same time they were added to *.po files.

In this example ugettext or ugettext_lazy functions should be used only after extracting messages from database.

Eduard Stepanov
  • 1,183
  • 8
  • 9
  • 1
    If the messages were not translated before adding to database, then why do you mark them with `ugettext_noop`? Similarly, in the example above, why not simply write `msg = "An error has occurred"`? – nalzok Mar 29 '17 at 06:56
  • If I don't mark it with ugettext_noop they will not be written in *.po files. When I need to translate a message firstly I get an appropriate row from database and then do something like this: ugettext(event_log_row.msg) So using `ugettext` in such a way won't add msg in *.po file. – Eduard Stepanov Mar 29 '17 at 07:04
  • So the reason why `msg` won't appear in a `.po` file is that it's passed to `ugettext` as a variable, rather than a string literal, so `django-admin makemessages` won't be able to detect it. Wrapping string literals with `ugettext_noop` solves this problem. Am I right? – nalzok Mar 29 '17 at 07:31
  • But when you use that function, it adds the text to the `.po` file. But if you remove the text later on, the translation from the po file is removed too. This implies we have to keep "visible" the `ugettext_noop()` function in the code. If I follow your example: (1) you wrapped every string with `ugettext_noop()` so you had this in your `.po` file. (2) you moved all your strings into the database (3) when you read from the database, you call `ugettext_lazy()` to translate. This is ok, but what did you do with all the strings wrapped with `ugettext_noop()`? You couldn't remove them right? – Olivier Pons Aug 17 '17 at 23:07
  • Of course if you remove `ugettext_noop` then appropriate strings will be removed from `.po` file. – Eduard Stepanov Aug 21 '17 at 11:49