I'm using {% trans %} template tag. Django docs say:
The {% trans %} template tag translates either a constant string (enclosed in single or double quotes) or variable content:
{% trans "This is the title." %} {% trans myvar %}
https://docs.djangoproject.com/en/4.0/topics/i18n/translation/#translate-template-tag
I found it 开发者_运维百科impossible to do {% trans myvar %} because myvar simply doesn't show up in django.po file after running makemessages command.
Am I using it wrong? Could some help me with this?
You can use the blocktrans
template tag in this case:
{% blocktrans %} This is the title: {{ myvar }} {% endblocktrans %}
{% trans myvar %}
just works. So check your PO file to make sure that the value of myvar
is in PO msgid.
<title>{% trans myvar %}</title>
For example if myvar
contains "Some Publisher"
you can write the following in the PO file:
msgid "Some Publisher"
msgstr "কিছু প্রকাশক"
Also make sure you have ran:
python manage.py compilemessages
Django can't guess what is in that variable, so you have to translate it yourself by adding both the english (msgid
) and the localized (msgstr
) strings.
My experience here is that variable translation does not work in templates on its own. However I came to a suitable solution when the content of the variables is known (I mean that they are not free text, but a set of choices you set in the database).
You need to force the translation in the view or in a filter tag.
To sum up:
- Use
blocktrans
in your templates - Force variables to be translated
- You either set variables in context that are already marked for transtalion
- or use a filter to translate them
- Generate translations in
.po
file
The story is like this:
views.py
def my_view(request):
return render(request, 'i18n_test.html', {'salutation':"Hola"})
templates/i18n_test.html
...
{% blocktrans %}{{ salutation }}{% endblocktrans %}
...
And when I render the template it always shows Hola whichever the current language is.
To force the translation, in the view we need to use ugettext.
def my_view(request):
return render(request, 'i18n_test.html', {'salutation':ugettext("Hola")})
However it is not always possible to access the view. So I prefer to use a filter like this.
templatetags/i18n_extras.py
@register.filter(name='translate')
def translate(text):
try:
return ugettext(text)
And the template becomes
...
{% blocktrans s=salutation|translate %}{{ s }}{% endblocktrans %}
...
And produces Hola, Hello, Ciao, Salut depending on the current language.
The disadvantage (as pointed out in the docs ) is that makemessages
does not automatically include these translations, so we need to include them manually. In django.po file:
locales/en/django.po
...
msgid "Hola"
msgstr "Hello"
...
You can translate the variable in the python code like here for settings.SITE_NAME
:
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
def processor004(request):
my_dict = {
'site_id004': settings.SITE_ID,
'site_name004': _(settings.SITE_NAME),
'installed_apps004': settings.INSTALLED_APPS,
'embedded_widget004': settings.EMBEDDED_WIDGET,
'base_template004': settings.BASE_TEMPLATE,
}
return my_dict
make own tags
from django.utils.translation import ugettext as _
@register.simple_tag
def trans2(tr, *args, **kwargs):
# print(':', kwargs)
trans = _(tr)
trans_str = trans.format(**kwargs)
return trans_str
in template:
{% trans2 columns_once.res_data.message with value=columns_once.res_data.recommend%}
in django.po
#: default_content.py:136
msgid "_audit_recommend_speed"
msgstr "Рекомендованная скорость до {value} сек"
It's a complex elegant solution that may help if you are translating values from model fields: http://django-modeltranslation.readthedocs.org
"Modeltranslation
The modeltranslation application is used to translate dynamic content of existing Django models to an arbitrary number of languages without having to change the original model classes."
To me, this happened when I had the TEMPLATES.DIRS
outside my Django project directory. Fetching the templates into the project directory solved the problem.
As one workaround, you can collect {% trans %}
(django 3.0 and below) or {% translate %}
(django 3.1 and above) tags between {% comment %}
and {% endcomment %}
in one template. This will save your efforts to repeat typing the same msgid should you have more than one language po file.
{% comment %}
{% trans "Tea" %}
{% trans "Clothes" %}
{% endcomment %.}
Make sure you run django-admin makemessages --all
after putting the aforementioned code.
精彩评论