Django i18n blocktrans vs trans - django

In Django templates, what exactly is the difference between these two:
{% blocktrans %}My Text{% endblocktrans %}
{% trans 'My Text' %}

From Django Docs
Trans template tag
The {% trans %} template tag translates either a constant string (enclosed in single or >double quotes) or variable content:
With a Trans tag, you are limited to a single constant string or variable. So you would have to use
{# These Would Work! #}
title>{% trans "This is the title." %}</title>
<title>{% trans myvar %}</title>
But could not use
{%trans "This is my title {{ myvar }}" %}
Blocktrans template tag
Contrarily to the trans tag, the blocktrans tag allows you to mark complex sentences
consisting of literals and variable content for translation by making use of placeholders:
With a Blocktrans, this kind of code is possible:
{% blocktrans with book_t=book|title author_t=author|title %}
This is {{ book_t }} by {{ author_t }}
{% endblocktrans %}
So Blocktrans is going to allow you to be a bit more complex and through in your output.
But to answer your question literally: not much. Except for the presentation style, both will be sent to the translator as the string 'My Text'

Related

How to declare variables inside Django templates

How do I declare a variable in Django 1.8 Templates for example like this:
{% my_var = "My String" %}
And so that I can access it like this:
<h1>{% trans my_var %}</h1>
Edit:
To demonstrate my purpose of this, this is my code:
{% my_var = "String Text" %}
{% block meta_title %}{% trans my_var %}{% endblock %}
{% block breadcrumb_menu %}
{{ block.super }}
<li>{% trans my_var %}</li>
{% endblock %}
{% block main %}
<h1>{% trans my_var %}</h1>
Try using the with tag.
{% with my_var="my string" %}
{% endwith %}
The other answer is more correct for what you're trying to do, but this is better for more generic cases.
Those who come here solely from the question title will need this.
One way I like to use is:
{% firstof "variable contents" as variable %}
Then you use it as {{variable}} wherever you want without the necessity for nesting with blocks, even if you define several variables.
You can assign the translation to a variable which you can use throughout.
{% trans "my string" as my_var %}
{{ my_var }} {# You can use my_var throughout now #}
Documentation for trans tag which is an alias for translate tag, after Django-3.1
Full example with your code snippet
{% trans "String text" as my_var %}
{% block meta_title %}{{ my_var }}{% endblock %}
{% block breadcrumb_menu %}
{{ block.super }}
<li>{{ my_var }}</li>
{% endblock %}
{% block main %}
<h1>{{ my_var }}</h1>

How to specify context of translation in Django {% trans %} {% blocktrans %}?

Documentation of Django says Contextual markers are also supported by the trans and blocktrans template tags. but it not explained how to do it?
Can you help marking translation context since I have some words with several meanings.
In Python I can do in such way:
pgettext("month name", "May")
pgettext("verb", "May")
How to specify translation context in Django template?
{% blocktrans %}May{% endblocktrans %}
It is explained at the very end of their specific paragraphs:
https://docs.djangoproject.com/en/dev/topics/i18n/translation/#trans-template-tag
{% trans %} also supports contextual markers using the context keyword:
{% trans "May" context "month name" %}
https://docs.djangoproject.com/en/dev/topics/i18n/translation/#blocktrans-template-tag
{% blocktrans %} also supports contextual markers using the context keyword:
{% blocktrans with name=user.username context "greeting" %}Hi {{ name }}{% endblocktrans %}
{% blocktrans context "month name" %}May{% endblocktrans %}

Django: Passing the result of {% trans %} via a filter

I have a string that I want passed via the "linebreaks" filter.
{% trans "my string"|linebreaks %}
Doesn't work.
Is there another way ?
See filter.
{% filter force_escape|lower %}
{% blocktrans %}This text will be translated, HTML-escaped, and will appear in all lowercase.{% endblocktrans %}
{% endfilter %}
If you need to filter before translation, you can also use:
{% blocktrans with value|filter as myvar %}
This will have {{ myvar }} inside.
{% endblocktrans %}

Translation in template with placeholders

in my .po file i have
msgid "This string will have %s inside."
How can i translate this in template?
I've tried:
{% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %}
and
{% blocktrans with value as value%}This string will have {{ value }} inside.{% endblocktrans %}
Neither works for me
As stated in the documentation, the strings should use Python's standard named-string interpolation syntax.
So {% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %} will use the translation string "This string will have %(value)s inside.".

django blocktrans and i18n in templates

I have an i18n problem in django:
This works fine :
{% trans cat.name %}
cat.name will be translated
But this doesn't work:
{% blocktrans with cat.name|slugify as cat_slug %}{{ cat_slug }}{% endblocktrans %}
cat.name is not translated
If I change the filter :
{% blocktrans with cat.name|capfirst as cat_slug %}{{ cat_slug }}{% endblocktrans %}
I can see that the filter is working, but there is no translation...
I'm only just getting started with Django internationalization, but I think you're misunderstanding how the {% blocktrans %} tag handles placeholders.
The point of blocktrans is to allow the text around the placeholders to be translated. It won't translate anything inside {{...}}.
If you look at the generated .po file, you'll see that the following template code:
{% blocktrans %}This is my variable: {{variable}}{% endblocktrans %}
Will get converted into something like the following:
msgid:"This is my variable: %s"
I don't think you can translate a variable within a blocktrans tag. You can probably do constant strings with {% blocktrans with _("string") as x %}{{x}}{% endblocktrans %} but I can't think why you'd want to.
You'll have to do what you want in your view or model code I think.
This works:
{% filter slugify %}{% trans cat.name %}{% endfilter %}
As Tom pointed out blocktrans will preserve what you put inside the with statement instead of translating it. What you need to do is use the with before the translation. In your example, it would look like this:
{% with cat_slug=cat.name|slugify %}
{% trans cat_slug %}
{% endwith %}
P.S. I know I'm answering a 6yr old question, but I've run across this exact situation a couple times now and haven't seen a SO question/answer that handles it.
{% blocktrans with cat.name as cat_slug %}{{ cat_slug|capfirst }}{% endblocktrans %}
?
EDIT: you were right the doc says the filter as to be placed in the blocktrans
{% blocktrans with cat_slug=cat.name|capfirst %}{{ cat_slug }}{% endblocktrans %}