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

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

Related

How simplify calling include with multiple viariables in Django template?

I want to simplify (make more readable) Django template code:
{% comment %}
required variables:
group_id = 'exclude-brands-group'
select_name = 'exclude-brands'
entities = 'excludeBrandsSets'
add_keyword_name = {% trans 'Brand' %}
url_edit_keywords = {{ url_project_filter_exclude_brands_edit_keywords }}
{% endcomment %}
{% with group_id='exclude-keywords-group' select_name='exclude-keywords' %}
{% with entities=excludeKeywordsSets %}
{% trans 'Words' as add_keyword_name %}
{% with url_edit_keywords=url_project_filter_exclude_keywords %}
{% include 'web_site/seo/frontend/seo/filtered_keyword_idea/template/keyword_filter_group.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
But I do not have idea how to reduce number of with tags - since include is only one line command. I have not idea how simplify trans. Do you know some simpler way to pass variables to templates?
The include tag lets you pass additional context to the template. That means you don't need separate with tags (although the downside is you end up with very long lines). There isn't any way to include the trans tag.
{% trans 'Words' as add_keyword_name %}
{% include 'web_site/seo/frontend/seo/filtered_keyword_idea/template/keyword_filter_group.html' with group_id='exclude-keywords-group' select_name='exclude-keywords' entities=excludeKeywordsSets url_edit_keywords=url_project_filter_exclude_keywords %}

Django template: check for empty query set

Is there a way to check for an empty query set in the Django template? In the example below, I only want the NOTES header to be displayed if there are notes.
If I put an {% empty %} inside the "for" then it does display whatever is inside the empty tag, so it knows it's empty.
I'm hoping for something that does not involve running the query twice.
{% if notes - want something here that works %}
NOTES:
{% for note in notes %}
{{note.text}}
{% endfor %}
{% endif %}
Clarification: the above example "if notes" does not work - it still displays the header even with an empty query set.
Here's a simplified version of the view
sql = "select * from app_notes, app_trips where"
notes = trip_notes.objects.raw(sql,(user_id,))
return render_to_response(template, {"notes":notes},context_instance=RequestContext(request))
Edit: the view select selects from multiple tables.
Have a look at the {% empty %} tag.
Example from the documentation
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% empty %}
<li>Sorry, no athletes in this list.</li>
{% endfor %}
</ul>
Link: https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#for-empty
If you are interested in a table, or some kind of heading if there are results, add the forloop.first:
{% for athlete in athlete_list %}
{% if forloop.first %}
Athlete Name:
{% endif %}
{{ athlete.name }}
{% empty %}
Sorry, no athletes in this list.
{% endfor %}
Try {% if notes.all %}. It works for me.
In your view check whether notes is empty or not. If it is then you pass None instead:
{"notes": None}
In your template you use {% if notes %} as normal.
It's unfortunate that you're stuck using a raw query set - they're missing a lot of useful behavior.
You could convert the raw query set into a list in the view:
notes_as_list = list(notes)
return render_to_response(template, {"notes":notes_as_list},context_instance=RequestContext(request))
Then check it as a boolean in the template:
{% if notes %}
Header
{% for note in notes %}
{{ note.text }}
{% endfor %}
{% endif %}
You could also make it happen without conversions using forloop.first:
{% for note in notes %}
{% if forloop.first %}
Header
{% endif %}
{{ note.text }}
{% endfor %}
What about:
{% if notes != None %}
{% if notes %}
NOTES:
{% for note in notes %}
{{ note.text }}
{% endfor %}
{% endif %}
{% else %}
NO NOTES AT ALL
{% endif %}
Your original solution
{% if notes %}
Header
{% for note in notes %}
{{ note.text }}
{% endfor %}
{% endif %}
Works now with Django 1.7 and thanks to QuerySet caching, it does not cost and extra query.
Often the right way to do this is to use the {% with ... %} tag. This caches the query so it runs only once and also gives you more flexibility with your markup than using {% empty %}.
{% with notes as my_notes %}
{% if my_notes %}
<ul>
{% for note in my_notes %}
<li>{{ note }}</li>
{% endfor %}
</ul>
{% else %}
<p>Sorry, no notes available</p>
{% endif %}
{% endwith %}
With this particular example I'm not sure how useful it is but if you're querying Many-to-Many field, for instance, it's likely what you want to do.
Use {% empty %} in django templates
{% if list_data %}
{% for data in list_data %}
{{ data.field_1 }}
{% endfor %}
{% else %}
<p>No data found!</p>
{% endif %}
We can write above code with {% empty %}.
{% for data in list_data %}
{{ data.field_1 }}
{% empty %}
<p>No data found!</p>
{% endfor %}

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

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