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

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

Related

how to avoid extra spacing in template while using if endif condition in template django

i am retrieving information from the database and using {%if%} and {%endif%} condition so if that field is blank it does not cause any problem but when that field does not have any value it creates a new blank line in place of that looks bad in styling I saw an answer use this {%if -%} {%- endif %}it doesn't work and throws the error all I want if field is blank do not create any new blank line and render second line below that without creating any whitespace
any suggestion will be helpfull
You could format like this:
My first line{% if second_line %}<br>
{{second_line}}{% endif %}<br>
My third line
The idea being if second_line doesn't exist it won't render that <br>
You can use the built in templatetag
{% spaceless %}
Space less content here
{% endspaceless %}
As per the documentation that can be found here:
https://docs.djangoproject.com/en/4.1/ref/templates/builtins/#spaceless
Thespaceless tag:
Removes whitespace between HTML tags. This includes tab characters and newlines.
{% spaceless %}
<p>
Foo
</p>
{% endspaceless %}
Would result in:
<p>Foo</p>

Using expressions inside tags

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

Using multiple filters for django text? [duplicate]

For me this works:
{{ game.description|safe }}
But this fails:
{{ game.description|safe|slice:"65" }}
Is there a way to apply two or more filters on a variable in Django templates?
Although it's quite past when the OP posted the question, but for other people that may need the info, this seems to work well for me:
You can rewrite
{{ game.description|safe|slice:"65" }}
as
{% with description=game.description|safe %}
{{description|slice:"65"}}
{% endwith %}
Is description an array or a string?
If it is a string, you might want to try truncatewords (or truncatewords_html if the description can contain HTML),
{{ game.description|safe|truncatewords:65 }}
Reference: Built-in filter reference, truncatewords.
(I'm new to Django so my apologies if slice works on strings.)
change
{{ game.description|safe|slice:"65" }}
to
{{ game.description|safe|slice:":65" }}
you are missing the colon
This may work:
{% filter force_escape|lower %}
This text will be HTML-escaped, and will appear in all lowercase.
{% endfilter %}
Reference: Built-in tag reference, filter.

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

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.