Как правильно добавить записи для вычисленных значений в файл сообщений интернационализации django?

Документация Django гласит:

Предостережение с использованием переменных или вычисленных значений, как в предыдущем два примера, это то, что утилита для перевода строки Django, django-admin.py makemessages, не смогут найти эти строки.

Это нормально со мной, я готов предоставить переводы для всех возможных значений переведенной переменной вручную. Но как это сделать?

Скажем, у меня в моем шаблоне код:

{% trans var %}

var извлекается из базы данных, и я знаю все возможные значения - пусть говорят, что возможными значениями являются "Алиса" и "Боб".

Я думал, что все, что мне нужно сделать, это указать такие записи:

msgid "Alice"
msgstr "Alicja"

в файле django.po. К сожалению, всякий раз, когда я запускаю djangoadmin makemessages после этого, эти записи закомментируются:

#~ msgid "Alice"
#~ msgstr "Alicja"

Что я делаю неправильно? Я неправильно понял идею перевода вычисленных значений?

Ответ 1

В настоящее время мы также выясняем это. Хотя мы не сделали этого правильно, у нас есть довольно досадный уродливый хак, чтобы обойти его.

Мы просто определяем функцию "dummy" где-то в коде (например, ваши models.py или даже settings.py) и заполняем ее всеми строками, для которых нам нужен перевод.

from django.utils.translation import ugettext_lazy as _, pgettext

def dummy_for_makemessages():
    """
    This function allows manage makemessages to find the forecast types for translation.
    Removing this code causes makemessages to comment out those PO entries, so don't do that
    unless you find a better way to do this
    """
    pgettext('forecast type', 'some string')
    pgettext('forecast type', 'some other string')
    pgettext('forecast type', 'yet another string')
    pgettext('forecast type', 'etc')
    pgettext('forecast type', 'etc again')
    pgettext('forecast type', 'and again and again')

Эта функция никогда не вызывается, но просто ее определение предотвращает получение комментариев от сообщений makemessages.

Не самое элегантное решение, но оно работает.

Ответ 2

Есть один хороший способ сделать это! (Я знаю, потому что мне довелось работать над одним и тем же кодом).

Прежде всего - это значение вычисляется где-то. Итак, в вашем действии вы можете:

context['var'] = 'good' if condition(request) else 'bad'

а затем в шаблоне:

{% if var == 'good' %}
    {% trans "Congratulations, var equals: "}
{% else %}
    {% trans "Oops, var equals: "}
{% endif %}
{% trans var %}

У вас могут быть разные значения, которые могут стать непрактичными... Если вы не используете этот трюк:

_ = lambda x: x 
context['var'] = _('good') if condition(request) else _('bad')

Вам нужно сделать _ что-то локальное, если вы не хотите сталкиваться с ugettext_lazy и т.д.

Таким образом, вы не:

  • перевод преждевременно
  • с помощью некоторой функции lame "dummy" с избыточностью, чтобы "перечислить" ваши переведенные строки.
  • испортить и отказаться от manage.py makemessages

Ответ 3

Я решил решить это с помощью аналогичного решения, предложенного в ответе @StFS.

Когда я использовал pgettext('forecast type', 'some string'), то использование {% trans varName %} в моем шаблоне все равно возвращает "некоторая строка" вместо "Новый текст" для перевода.

Итак, я изменил синтаксис функции на gettext('some string').

Теперь использование {% trans varName %} даст "новый текст" в моем шаблоне.