Jinja2 appending items to a list in a for loop - jinja2

I need to build a list of urls to some static images in my html. I am using jinja templates and as I understand this should work -
{% set urlList=[] %}
{% for i in data['a-list-of-tuples'] %}
{% urlList.append(url_for('static', filename='sample_out/segmented/' + i[0])) %}
{% endfor %}
But I get the error - jinja2.exceptions.TemplateSyntaxError: Encountered unknown tag 'urlList'
However this works -
{% set urlList=[] %}
{% for i in data['a-list-of-tuples'] %}
{{ urlList.append(url_for('static', filename='sample_out/segmented/' + i[0])) }}
{% endfor %}
I am not sure what is happening here, can someone shed some light on this please?

Related

How to remove empty line in Jinja (exporting from readwise to logseq)

I am trying to export highlights from readwise to logseq with correct page properties.
However for some pages an empty line appears which prevents all properties to appear correctly.
How can I fix this?
This is the current jinja code:
author:: [[{{author}}]]\
full-title:: "{{full_title}}"\
category:: #{{category}}\
if url %}url:: {{url}}{% endif %}\
if document_note %}document_note:: {{document_note}}{% endif %}\
if document_tags %}tags:: {% for tag in document_tags %}#[[{{tag}}]] {% endfor %} {% endif %}
if image_url %}![]({{image_url}}){% endif %}`
ine issue for example: If document note is empty it still creates a line for that property
I managed to fix it:
author:: [[{{author}}]]\
full-title:: "{{full_title}}"\
category:: #{{category}}\
{% if url %}url:: {{url}}{% endif -%}\
{% if document_note %}document_note:: {{document_note}}{% endif -%}
{% if document_tags %}tags:: {% for tag in document_tags %}#[[{{tag}}]] {% endfor %} {% endif %}\
{% if image_url %}![]({{image_url}}){% endif %}
Changes include adding - before the % in the endif

how to displayliquid code in Jeckyll post

Hello I am trying to make a post using jeckyll and as part of my post I would like to show some liquid code. The post should display the IF statement as part of the post text (example below).
{% if customer and customer.tags contains 'Wholesale' %}
{% endif %}
I have tried to post this as
{% highlight liquid %}
{% if customer and customer.tags contains 'Wholesale' %}
{% endif %}
{% endhighlight %}
and also
{% highlight markdown %}
{% if customer and customer.tags contains 'Wholesale' %}
{% endif %}
{% endhighlight %}
but anything I try seems to be still executing the liquid code.
Is there a way to display the IF statement my post?
Try wrapping your liquid code in {% raw %} {% endraw %} like this:
{% highlight liquid %}
{% raw %}
{% if customer and customer.tags contains 'Wholesale' %}
{% endif %}
{% endraw %}
{% endhighlight %}
The raw tag will disable any liquid processing and output your code as desired.

How to check if a value is present in a list?

I would like to get the list of posts having a specific tag in their front matter (*)
I tried the code below, which iterates over all the tags of the current post pages (the current tag is t), then iterates over all the posts (p) to check if they have this tag (and just outputs the title, for debugging reasons):
{% for t in page.tags %}
{% for p in site.posts %}
{% if t in p.tags %}
{{ p.title }}
{% endif %}
{% endfor %}
{% endfor %}
The line {% if t in p.tags %} seems to fail (I come form a Python background so I gave it a try) and I cannot find the in operator in liquid. Does it exits?
(*) I am mentioning what I want to achieve in case there is a more straightforward way to do that but I am still interested in the general question.
Following your example it can be done with the contains tag:
contains can also check for the presence of a string in an array of
strings.
{% if product.tags contains "outdoor" %}
This product is great for
using outdoors!
{% endif %}
So to get the list of posts having a specific tag in their front matter (in this case the posts with the tag mytag):
{% assign posts_with_mytag = site.posts | where_exp:"item",
"item.tags contains 'mytag'" %}
{% for post in posts_with_mytag %}
{{post.title}}
{% endfor %}
Following-up on #maracuny's answer, the corrected code from my question for completeness:
{% for t in page.tags %}
{% for p in site.posts %}
{% if p.tags contains t %}
{{ p.title }}
{% endif %}
{% endfor %}
{% endfor %}

How to delete the odd attributes while rendering form

I rewrite some widgets in bootstrap_3_layout.html.twig and I don't want the form fields to have some attributes while they are rendered.
I've found out the sequence of some widgets
button_widget → button_row → form_widget → widget_attributes
And I made a little change
{% block widget_attributes %}
{% spaceless %}
{# bla-bla-bla #}
{% for attrname, attrvalue in attr %}
{% if attrname in ['placeholder', 'title'] %}
{{ attrname }}="{{ attrvalue|trans({}, translation_domain) }}"
{% elseif attrname not in ['first','last','data-help'] %}
{{ attrname }}="{{ attrvalue }}"
{% endif %}
{% endfor %}
{% endspaceless %}
{% endblock widget_attributes %}
But it doesn't work for buttons.
I'm not sure what you are achieving but you can intercept the odd index of a twig loop as follow:
{% for attrname, attrvalue in attr %}
{% if loop.index is odd %}
odd
{% else %}
even
{% endif %}
{% endfor %}
More info on loop variable and odd test function.
Hope this help
It's strange, but the form layout in twig_bridge has some widgets to work with attributes.
1. for inputs `widget_attributes`
2. for buttons `button_attributes`
3. for another element `widget_container_attributes`
For each widget, there are next blocks in twig-bridge:
{name_of_widget}_widget - main block to render an element
{name_of_widget}_label
{name_of_widget}_row
And for attributes, there are
widget_attributes
widget_container_attributes
button_attributes
attributes
I just used incorrect one :)
Thank all for your patience.

Jekyll (Liquid): Setting post state in included templates

Maybe this is a case of a Python programmer trying to work with Ruby and maybe this is a "feature" -- I don't know. For the life me I can't figure out how to set state on posts during the rendering process.
I have a _layout that just calls include twice:
{% include templateA %}
{% include templateB %}
templateA walks the posts and renders some of them on the basis of some_condition.
{% for post in site.posts %}
{% if some_condition %}
<!-- Render the post -->
{% assign post.rendered = true %}
{% endif %}
{% endfor %}
templateB attempts to walk the posts and render the rest:
{% for post in site.posts %}
{% unless post.rendered %}
<!-- Render the post -->
{% endif %}
{% endfor %}
This does not work as expected. I have also tried the {% assign post[rendered] = true %} syntax. No errors are thrown; just silent failure.
Where am I failing here? Is my mental model for the rendering process just totally wrong? Thanks!
Your first though was nearly ok. The unless tag does the contrary of if.
But you cannot change jekyll's variables, they are "freezed".
So, this might work :
templateA
{% for post in site.posts %}
{% if same_condition %}
<!-- Render the post -->
{% endif %}
{% endfor %}
With the same condition unless will render posts not rendered by the first loop.
templateB
{% for post in site.posts %}
{% unless same_condition %}
<!-- Render the post -->
{% endunless %}
{% endfor %}