I need to be able to generate the links certain number of times (stored in int variable)Is there a way to do it out of the box with twig's for loop?
{% for i in numberOfLoops %}
{{ i }}. Some data
{% endfor %}
The above example do not work. I googled it but did not find actual solution. Any support would be very appreciated.
EDIT:
I also tried:
{% set k = 10 %}
{% for i in 0..k %}
{{ i }}
{% endfor %}
but this generates an exception:
com.lyncode.jtwig.exception.ParseException: Wrong binary operation syntax
Explanation: Input position (line 15, pos 27):
{% for i in 0..k %}
^
I found the working example:
{% set k = 10 %}
{% for i in range(1, k) %}
{{ i }}
{% endfor %}
Source: http://twig.sensiolabs.org/doc/templates.html (not very intuitive to find indeed).
I already had a loop in place to iterate over, I solved this for myself with the slice filter.
{% for link in links|slice(0, 12) %}
http://twig.sensiolabs.org/doc/tags/for.html#iterating-over-a-subset
Try this:
{% set k = 10 %}
{% for i in 0..k %}
{{ i }}
{% endfor %}
Documentation: http://twig.sensiolabs.org/doc/tags/for.html
Related
In Python, what I would like to achieve is:
count = 0
for i in range(count, count+5):
count
What is the syntax for this with Jekyll, if it is possible?
{% assign count = 0 %}
{% for i in (...) %}
{{ i }}
{% endfor %}
You can define range with integers {% for i in (1..10) %} or with variables {% for i in (myVar..myOtherVar) %}
I'm currently comparing two array's and their id's. If they match it should output a count value. It is totally working but I'm thing if there is another way in doing this rather than:
{% for count in product_count %}
{% if count.term_id == child._menu_item_object_id %}
{{ count.count }}
{% endif %}
{% endfor %}
Thanks for any support! :)
Thanks to #DarkBee
{% for count in product_count if count.term_id == child._menu_item_object_id %}
I have a folder of images that I'd like to render on a page. I'd like these images to be ordered/filtered a particular way. To do that, I understand that the images need to first be together in an array.
I therefore start with an empty array:
{% assign my_array = "" %}
I then loop through the image folder, and attempt different ways of pushing each image into my_array. Example:
{% for image in site.static_files %}
{% if image.path contains "assets/images/target-folder" %}
<!-- Push image into array -->
{{ my_array | push: image }}
{% endif %}
{% endfor %}
Ideally, I can then use this array as intended:
{% for image in my_array | sort:"date" | reverse %}
<!-- show image -->
{% endfor %}
I'm aware that I could make a data file with the images, but I'd like to avoid needing to take that extra step. Thanks for reading.
You are almost there, the way of how you are creating the array it is the only thing to fix.
This {% assign my_array = "" %} creates an empty string. One easy way to create an array in Liquid is to split the above:
{% assign my_array = "" | split: ',' %}
Now you can push items into the array inside a for loop in the following way:
{% for image in site.static_files %}
{% if image.path contains "assets/images/target-folder" %}
<!-- Push image into array -->
{% assign my_array = my_array | push: image %}
{% endif %}
{% endfor %}
Also note that you can do this without a loop using where/where_exp filters:
{% assign my_array = site.static_files |
where_exp: "item", "item.path contains 'assets/images/target-folder'" %}
or:
{% assign target_folder = "assets/images/target-folder" %}
{% assign my_array = site.static_files |
where_exp: "item", "item.path contains target_foler" %}
(Although, unlike the accepted answer, this doesn't precisely correspond to the question's title, it's still a useful option in the described example.)
This solution worked for me:
{% assign namesArr = '' %}
{% for animal in animals %}
{% assign namesArr = namesArr | append: animal.name %}
{% if forloop.last == false %}
{% assign namesArr = namesArr | append: "," %}
{% endif %}
{% endfor %}
{% assign namesArr = namesArr | split: "," %}
Now namesArr is array, we can check array contains some value: https://stackoverflow.com/a/30823063/5638975
I made a dummy "related posts" in Jekyll 3.2.1 with the following solution:
{% for post in site.posts limit: 4 %}
{% if page.author == post.author and page.title != post.title %}
<div class="post-stream-item">
<a href="{{ post.url | prepend: site.baseurl }}" title="{{ post.title }}"><div class="post-stream-content">
<img src="{{ post.thumbnail }}" width="80" height="auto" /><span class="post-stream-item-meta"><h3>{{ post.title }}</h3><p>{{ post.author }} on {{ post.date | date: "%b %-d, %Y" }} • {% assign words = post.content | number_of_words %}
{% if words <= 160 %}
1 min
{% else %}
{{ words | plus: 159 | divided_by:160 }} mins
{% endif %} read</p></span></div></a></div>{% if forloop.last == false %}<hr>{% endif %}
{% endif %}
{% endfor %}
The for loop iterates through the posts list in the site and gives
it a limit
If the author of the current post is the same as the author of the
iterated post, but the title is not the same, then it fills out the
jinja bindings.
The problem is with the {% if forloop.last == false %}<hr>{% endif %} part, cause if there is more iterable (post) in the forloop, it will display the <hr> tag, even if it's the last element shown to the user.
Is there any attribute to refer to the penultimate element of the list or any better solution to this?
There isn't going to be a simple out-of-the-box one-line solution for this. Think about it this way: you're essentially asking for a feature that looks ahead in time and figures out whether this is the last time the if statement will evaluate to true. Jekyll is great, but it can't predict the future!
You could do this yourself by using two loops: one that loops through and counts how many <hr> elements you should show. Then another that actually prints stuff out, checking against the count you came up with to decide whether to print the <hr> element.
Or you could just use CSS to hide the last <hr> element. Google is your friend here.
Print a certain number of posts with no print condition
Solution : use loop limit
{% for post in site.posts limit: 4 %}
... output code here
{% endfor %}
You will print exactly 4 posts and forloop.last always works.
Print a certain number of posts with a print condition in the loop
Solution : use where filter, a counter and break
Now that you include a conditional printing :
you don't know which and how many posts will be printed.
if you don't print last post, you have an HR at the end of your list.
If you want to know how many posts you can print, you can use {% assign authorsPosts = site.posts | where: "author", page.author %} and authorsPosts.size.
This code will do it nicely, even if available posts number is less than your limit.
{% comment %} +++++ Max number of posts to print +++++ {% endcomment %}
{% assign limit = 4 %}
{% comment %} +++++ Select authors posts +++++{% endcomment %}
{% assign authorsPosts = site.posts | where: "author", page.author %}
{% comment %} +++++ If author's Posts number is less than limit, we change the limit +++++ {% endcomment %}
{% if limit >= authorsPosts.size %}
{% comment %} +++++ Number of "listable" posts is author's posts number less 1 (the one actually printed) +++++ {% endcomment %}
{% assign limit = authorsPosts.size | minus: 1 %}
{% endif %}
{% assign postsCounter = 0 %}
{% for post in authorsPosts %}
{% if page.author == post.author and page.title != post.title %}
{% assign postsCounter = postsCounter | plus: 1 %}
<h3>{{ post.title }}</h3>
{% comment %} +++++ Prints hr only if we are not printing the last post +++++ {% endcomment %}
{% if postsCounter < limit %}<hr>{% endif %}
{% comment %} +++++ Exit for loop if we reached the limit +++++ {% endcomment %}
{% if postsCounter == limit %}{% break %}{% endif %}
{% endif %}
{% endfor %}
So I have an existing array, I want to run a for loop through it and recreate new arrays. I am trying to figure out how to create my own array directly on volt. Here is my code:
{% set oNomesAgendaAmigos = [], oNomesAgendaRecomendado = [], oNomesAgendaAmigosRecomendado = [] %}
{% for oNomeAgenda in oNomesAgenda %}
{% set oNomesAgendasTotal = oNomeAgenda.cliente_nome %}
{% if oNomeAgenda.ind_amigo == 1 %}
{% set oNomesAgendaAmigos = oNomeAgenda %}
{% endif %}
{% if oNomeAgenda.ind_recomendado == 1 %}
{% set oNomesAgendaRecomendado = oNomeAgenda.cliente_nome %}
{% endif %}
{% if oNomeAgenda.ind_recomendado == 1 AND oNomeAgenda.ind_amigo == 1 %}
{% set oNomesAgendaAmigosRecomendado = oNomeAgenda.cliente_nome %}
{% endif %}
{% endfor %}
Last time i have checked there were no mechanism for setting table bit by bit in Volt. The walk-around would be to use array_merge() or implement own filter/method into Volt engine.
Anyway it's a bit against MVC principles. You should set all tables you need over your PHP part of code.
To loop ever array with indexes inside loop you use that trick:
{% for index, value in numbers %}
{{ index }}: {{ value }}
{% endfor %}
I also really appreciate this part of Volt Documentation.