Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django translate variable content in template

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?

like image 309
thoslin Avatar asked Jul 01 '11 10:07

thoslin


4 Answers

You can use the blocktrans template tag in this case:

{% blocktrans %} This is the title: {{ myvar }} {% endblocktrans %} 
like image 102
Jeff Wilcox Avatar answered Nov 11 '22 15:11

Jeff Wilcox


{% 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 
like image 41
David Dehghan Avatar answered Nov 11 '22 16:11

David Dehghan


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:

  1. Use blocktrans in your templates
  2. Force variables to be translated
    • You either set variables in context that are already marked for transtalion
    • or use a filter to translate them
  3. 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"
...
like image 24
kiril Avatar answered Nov 11 '22 15:11

kiril


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.

like image 21
Gabi Purcaru Avatar answered Nov 11 '22 16:11

Gabi Purcaru