django blocktrans and i18n in templates - django

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 %}

Related

What is the difference between `blocktrans` and `blocktranslate`? Between `trans` and `translate`?

What is the difference between these two lines of code in a Django template?
{% blocktrans %}Example{% endblocktrans %}
{% blocktranslate %}Example{% endblocktranslate %}
Likewise, what is the difference between these two lines of code in a Django template?
{% trans "Example" %}
{% translate "Example" %}
There is no difference. {% blocktrans %} is equivalent to {% blocktranslate %}, it's just an alias. Likewise, {% trans %} is equivalent to {% translate %}.

How to translate in django a complex variable with filter and idx

Is someone know how to translate in Django a complex variable with filter (|) and customtag (idx) like:
<li data-role="list-divider">{{ controlItem|idx:0|upper }}</li>
I have no problem with simple variable like:
{% trans controlSubitem.name %}
Thank you very much for your help.
{% with controlItem|idx:0|upper as variable %}
{% trans variable %}
{% endwith %}
https://docs.djangoproject.com/en/1.4/ref/templates/builtins/#with

URL output in template is empty

URL pattern declaration from views.py
url(r'^intentions/(\d+)/$', 'intentions.views.show'),
When I am writing address directly, like intentions/1 works ok, but when I trying to display URL show for object like:
{% for i in intentions %}
{% url 'intentions.views.show' i.id as iUrl %}
<li>{{ i }}</li>
{% endfor %}
I am ending with empty href. Could someone give me any advice?
If you are using Django 1.3 or 1.4, make sure you are loading the new url tag. Add the following line to the top of your template:
{% load url from future %}
If you are using Django 1.4 or earlier, and you haven't loaded the new url tag as above, then you need to remove the single quotes from the url pattern:
{% url intentions.views.show i.id as iUrl %}
As an aside, it's recommended to name your url pattern:
url(r'^intentions/(\d+)/$', 'intentions.views.show', name='show_intention'),
Then change your template to:
{% for i in intentions %}
{% url 'show_intention' i.id as iUrl %}
<li>{{ i }}</li>
{% endfor %}
you could try
{% for i in intentions %}
<li><{{ i }}</li>
{% endfor %}
don't use {% url 'intentions.views.show' i.id as iUrl %}, it's maybe confused.
Also,you could try modifiy the url as follow
url(r'^intentions/(\d+)/$', 'intentions.views.show', name="intention_view"),
then,
{% for i in intentions %}
{% url "intention_view" i.id as iUrl %}
<li>{{ i }}</li>
{% endfor %}
If there are also ending empty href,try the first method.
'intentions.views.show'
Also give a name='' to your URL and use it in your template code.

Django template {% trans %} pluralization

According to this section in the Django docs I should use {% blocktrans %} for cases where I need to translate pluralizations. However, with an example like the following, isn't there something more convenient I can do?
{% blocktrans count video.views.count as views %}
The video has been viewed <span>{{ views }}</span> time
{% plural %}
The video has been viewed <span>{{ views }}</span> times
{% endblocktrans %}
I tried to do the following:
{% blocktrans %}time{% plural %}times{% endblocktrans %}
But it threw TemplateSyntaxError: 'blocktrans' doesn't allow other block tags (seen u'plural') inside it
You forgot the count variable as variable_name in the blocktrans tag
The value of that variable will be used to detect if it's plural or not.
{% blocktrans count variable as variable_name %}
time
{% plural %}
{{ variable_name }} times
{% endblocktrans %}
You can use:
{% blocktrans with video.views.count|pluralize as foo and video.views.count as views %}
The video has been viewed <span>{{ views }}</span> time{{ foo }}
{% 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 %}