Using expressions inside tags - django

I'd like to capitalize a string variable and translate it at the same time, but i can't find how to do this in the api docs.
i.e. this is throwing an error:
{% trans {{ someString | capfirst }} %}

In Django if you start curly brackets {{ or {%, then inside you cannot open another one. Just use it, as you would use it without extra brackets.
{% trans {{ someString | capfirst }} %}
# change to:
{% trans someString|capfirst %}
PS. As I think it's not necessary, it's a good practice not to put spaces right before and next to |.

Related

How to make strings from my database show up in my localisation .po file in Django?

in one of my python projects, I'm looping through a list of countries which is stored in my SQLite database:
{% if europe %}
{% for country in europe %}
<figcaption>{{ country.Name_fr }}</figcaption>
{% endfor %}
{% endif %}
I am using localization so I have a locale folder with .po files with which I handle the different translations. However I would like to have the database strings (from {{ country.name_fr }}) show up in these .po files. This means I would have to include a translate tag but if I try it, it shows an error. This:
<figcaption>{% translate {{ country.Name_fr }} %}</figcaption>
leads to this:
TemplateSyntaxError at /
Could not parse the remainder: '{{' from '{{'
Any help would be appreciated
As translate template tag documentation states
It’s not possible to mix a template variable inside a string within {%
translate %}. If your translations require strings with variables
(placeholders), use {% blocktranslate %} instead.
So you could use blocktranslate
{% blocktranslate %}
{{ country.Name_fr}}
{% endblocktranslate %}
Even simpler for your use case would be to just pass variable to translate
The {% translate %} template tag translates either a constant string
(enclosed in single or double quotes) or variable content
{% translate country.Name_fr %}

using a loop result as a variable for child loop

I think the best way to describe is problem is with an example.
{% for content in contents %}
{% for stuff in {{content}} %}
{{stuff}}
{% endfor %}
{% endfor %}
I am using google app engine webapp templates. I can't seem to use a result from the parent forloop {{content}} as a variable for its child forloop. TemplateSyntaxError: Could not parse the remainder: '{{content}}' from '{{content}}' Is it possible to do this? Thanks!!
You can use only content without braces around:
{% for content in contents %}
{% for stuff in content %}
{{ stuff }}
{% endfor %}
{% endfor %}
When you are inside the first for-loop, content exists in the context, as any other variable. Same thing for stuff in the inner loop. Plus, blocks are generally using argument as variables, except in it is surrounded by quotes.
The {{ }} notation can be use to only display the variable in the document.

How to truncate/slice strings on Django Template Engine?

index.html
<td>{% if place or other_place or place_description%}{{ place}} {{ other_place}} {{place_description}}</td>
This is displaying all the data in template.I want to truncate the string if it is more than length 80.
Conditions are,
1.If place variable have more than 80 character,it should truncate their and need not show the other two variable like other_place and place_description.
2.If place variable and other_place variable making more than 80 character,in this case it should truncate from place_variable don't need to show place_description variable.
3.If all the three are their and the 80th character is made from place_description,need to truncate from their.
All fields are not mandatory,so whatever field is comes to display,it should show only 80 character.
Need help to do this.
Thanks
You could use slice for pre-django 1.4:
{% if place or other_place or place_description%}
{% with place|add:other_place|add:place_description as pl %}
{% if pl|length > 80 %}
{{pl|slice:80}}...
{% else %}
{{pl }}
{% endif %}
{% endwith %}
{% endif %}
If you are using django 1.4 or greater,
You can just use truncatechars
{% if place or other_place or place_description%}
{% with place|add:other_place|add:place_description as pl %}
{{pl|truncatechars:80}}
{% endwith %}
{% endif %}
You could probably do it with a combination of add/truncatechars e.g.
{{ place|add:other_place|add:place_description|truncatechars:80}}
You could also use 'cut' which is part of django template builtins
for example if
{{ file.pdf.name}}
gives 'store/pdfs/verma2010.pdf'
{{ file.pdf.name | cut:'store/pdfs/'}}
Would give 'verma2010.pdf'
Took me way too long to find the answer in 2022. It's truncatechars, e.g.
{{ my_string|truncatechars:1 }}
https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#truncatechars

Is there a way to split text on whitespace in Liquid?

I'm trying to split a Jekyll post's contents into words, and have tried the following:
{% for word in post.content | split:' ' %}
{% do some stuff %}
{% endfor %}
Unfortunately this doesn't do anything; 'word' ends up as the whole post. I'm using this code on Github Pages, so unfortunately I can't write a plug-in to take care of this. Am I using the split filter incorrectly? Does Liquid support what I'm trying to do?
It seems that you can split on whitespace by using split: .
So you can try something like:
{% capture words %}{{ post.content | split: }}{% endcapture %}
or:
{% assign words = post.content | split: %}
From what I've tested so far it seems that you should use the latter (assign tag), as the capture tag seems to do an implicit join on the array elements when assigning the value to the variable.
Using:
{% for post in site.posts limit:1 offset:6 %}
{% assign words = post.content | split: %}
{% for word in words %}{{ word }} {% endfor %}
{% endfor %}
seems reproduce the post content in its entirety. The whitespace in the inner for loop matters.
Just as a note now, if you need to join some of the words back together with whitespace, the join tag seems to require quotes around the character, like so: join:' '.
Edit:
I ended up attempting to also do some splitting on whitespace, and while it worked in my development environment it didn't work on Github Pages. It looks like Pages is running version 2.2.2, whereas the split() filter was introduced in version 2.3.0. My development environment was running 2.4.1. Hopefully we can pester the fine folks at Github enough to get them to update their version of Liquid. :)
Filters (such as split) can only be used on {{ outputs }} not on {% tags %}.
You might be able to accomplish the split by using the capture function as follows:
{% capture 'foo' %} {{ post.content | split:' ' }} {% endcapture %}

How to put braces in django templates?

I need to produce an id surrounded by braces ( for example "{1234}" ). With the django template language, braces are also used to start a variable substitution, so I have some trouble in obtaining what I want. I tried
{{{ id }}}
{{ '{'id'}' }}
{{ '{'+id+'}' }}
{ {{ id }} }
None of these methods work, except the last one, which unfortunately produces "{ 1234 }", not what I want. I currently have two solutions : either I pass an id variable already containing the {} (ugly) or I write a custom filter and then write {{ id|add_braces }} (I prefer it).
Before going this way, I prefer to ask if a better solution exists.
Using escaped values does not work. Even if I add {% autoescape off %}%7B{% endautoescape %} I don't get the {, which is strange, but that's another problem.
Thanks
Edit: I wrote a quick filter. Pasting it here so someone else can use it as a template for writing a more complex one. To be put into python package application_path/templatetags/formatting.py
from django import template
from django.template.defaultfilters import stringfilter
register = template.Library()
#register.filter
#stringfilter
def add_braces(value):
return "{"+value+"}"
I think your answer can be found here:
http://docs.djangoproject.com/en/dev/ref/templates/builtins/#templatetag
In short, you want to use {% templatetag openbrace %} and {% templatetag closebrace %}.
Edit:
Django now also includes this functionality out of the box:
{% verbatim %} {{ blah blah }} {% endverbatim %}
{% templatetag openbrace %} become extremely verbose for e.g. javascript templates
I've used the verbatim tag from this gist with some success for exactly this purpose which lets you do something like
{{ request.user }}
{% verbatim %}
brackets inside here are left alone, which is handy for e.g. jquery templates
{{ this will be left }}
{% so will this %}
{% endverbatim }}
{% more regular tags (to be replaced by the django template engine %}
The recommendation from the Jinja templating language works with the Django templating engine as well:
http://jinja.pocoo.org/docs/dev/templates/#escaping
The solution is this:
{{ '{' }}{{ id }}{{ '}' }}
Of course the other two answers work, but this is one is less verbose and more readable, in my opinion.