Twig: negate containment operator IN - templates

I'm trying to negate IN.
Basically, I want to output true, when keyword1 is in keywords, but keyword11 isn't.
Please note: keyword11 ("my_keyword_11") starts with keyword1 ("my_keyword_1"). keywords has to stay a string, can't split/explode by the comma.
{% set keywords = 'my_keyword_1, my_keyword_2' %}
{% set keyword1 = 'my_keyword_1' %}
{% set keyword11 = 'my_keyword_11' %}
{% if ((keyword1 in keywords) and (keyword11 not in keywords)) %}
true
{% endif %}
Any ideas? Thanks in advance!

Your code is ok as you can view in this twigfiddle

Related

Regex in Go: How to replace only the capture group? [duplicate]

I've used regexp package to replace bellow text
{% macro products_list(products) %}
{% for product in products %}
productsList
{% endfor %}
{% endmacro %}
I could not replace "products" without replace another words like "products_list" and Golang has no a func like re.ReplaceAllStringSubmatch to do replace with submatch (there's just FindAllStringSubmatch). I've used re.ReplaceAllString to replace "products" with .
{% macro ._list(.) %}
{% for product in . %}
.List
{% endfor %}
{% endmacro %}
But I need this result:
{% macro products_list (.) %}
{% for product in . %}
productsList
{% endfor %}
{% endmacro %}
You can use capturing groups with alternations matching either string boundaries or a character not _ (still using a word boundary):
var re = regexp.MustCompile(`(^|[^_])\bproducts\b([^_]|$)`)
s := re.ReplaceAllString(sample, `$1.$2`)
Here is the Go demo and a regex demo.
Notes on the pattern:
(^|[^_]) - match string start (^) or a character other than _
\bproducts\b - a whole word "products"
([^_]|$) - either a non-_ or the end of string.
In the replacement pattern, we use backreferences to restore the characters captured with the parentheses (capturing groups).

if-statement doesn't work in for-loop

I have an issue with the if-statement and need some help. This is a short code-snippet in html:
{% for category in categories %}
{% if category == 'christmas' %}
<p>{{category}} 1</p>
{% else %}
<p>{{category}} 2</p>
{% endif %}
{% endfor %}
With the for-loop I walk through categories and check them with an if-statement for the string 'christmas'. The paragraph is always the second one, ending with a 2. Still, it appears that the category with the name 'christmas' comes up. That means, that in the if-statement "category" is different than in the p-tag. In fact, category is empty in the if-statement.
Why? Can someone help here, please. Thanks!
Edit: Added two pictures. On the right you see the output:
length is zero
showing no fit, although it should
I'm guessing you're looping over category objects from a model meaning categories is not a list of strings but a queryset? In that case you should do something like this:
{% for category in categories %}
{% if category.name == 'christmas' %}
<p>{{category}} 1</p>
{% else %}
<p>{{category}} 2</p>
{% endif %}
{% endfor %}
Replace .name by whatever your correct attribute is.
Your {{category}} is probably displayed correctly because of your __unicode__ or __str__ method.

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

Django if statement

Is it possible to use this code
{% if item.status == "0" %}
<td>Pending</td>
{% else %}
<td>Approved</td>
{% endif %}
if the item.status is an integer?
It seems to never go into the if statement and prints else all the time
Should i declare the variable first? eg something = item.status?
If yes then what is the correct syntax?
Remove the quotes around the 0 and it looks like it should work. See here
You are comparing it to a string "0", not am integer 0. That's the problem. The syntax is fine, just remove the quotes.
this should work.
{% ifequal item.status 0 %}
<td>Pending</td>
{% else %}
<td>Approved</td>
{% endifequal %}
Edit
just to clarify (as the other answers have mentioned) the issue is "0", comparing int == string, ifequal is just my preferred way of using the template tag.