Jekyll how can I use site.data.+variable? - jekyll

I would like to know if there's a way to use a variable after a data call in Jekyll?
Like this:
{% assign variable = items %}
{% assign images = site.data.folder.variable %}

You can use a variable as an object key using this notation:
{% assign images = site.data.folder[variable] %}

Related

jinja2 - create href with variable from loop

I'm try to create a dynamic href for a website
I've tried this:
(where "gruppe" is a list of servers)
{%- for item in groups[gruppe] %}
{% set url = 'https://cmk.abc.local/abc/check_mk/view.py?host=' + {{ hostvars[item]['openstack']['name'] }} + '&site=abc&view_name=host' %}
{{ hostvars[item]['openstack']['name'] }}.abc.local
{% endfor %}
Expected result should be:
https://cmk.abc.local/abc/check_mk/view.py?host=server01&site=abc&view_name=host#
Does anyone have an idea what I'm doing wrong?
It's tough to say without knowing the shape of the data. If you can post what "groups" looks like (as JSON) that would be helpful.
The first thing that stands out to me is "gruppe". Is that supposed to be a key in the groups object or is that supposed to be dynamic?
Try:
{%- for item in groups["gruppe"] %}
...

How to set loop.index as a variable in Jinja

{% for data in data_list %}
{% set data_index = {{loop.index}} %}
for data_dict in data:
pass
In my inner loop, I need to use the loop index in the outer loop, so I intend to set it to a variable as above. But the syntax is invalid.
How to do that? Or is there another way to get the outer loop index?
i think, you should not use Expressions({{..}}) inside statements ({%..%}), try this :
{% for data in data_list %}
{% set data_index = loop.index %}
for data_dict in data:
pass
You could use the built-in enumerate function for the same to get i as the variable and also use it in an inner loop if you want.
{% for i,data in enumerate(data_list) %}
{{ i }}
{% for j in range(i) %}
{% endfor %}
{% endfor %}
All you need to do is pass enumerate or whatever built-in python function you need as a parameter to the render template function as shown below
#app.get("/foo")
def foo():
return render_template("foo.html", enumerate=enumerate, range=range)

Using Jekyll, how do you alter an array's contents using a for loop?

Say I have an array thingy.foo = ['abc', 'def'] in my scope.
My goal is to be able to loop over all the items in thingy.foo and apply some conditional logic to it, overwriting the existing item in the array... Something like this:
{% for item in thingy.foo %}
{% assign thingy.foo[forloop.index0] = site.data.lookups[item] | default: item %}
{% endfor %}
What I am doing do the item is a bit irrelevant, the part I'm having issues with is updating the item in the array. The code compiles and runs. Within the loop, I can confirm that the "lookup" part works (if I assign it to t and inspect t then I get a looked up value, but thingy.foo[0] is still the original value).
Is it possible to update/overwrite arrays in Jekyll?
(this is intended for use on GitHub Pages, so I cannot use custom plugins).
It looks like you cannot mutate existing arrays... but you can loop over the initial array and mutate items into a new array, like this:
{% assign newArray = '' | split: '' %}
{% for item in thingy.foo %}
{% assign newItem = site.data.lookups[item] | default: item %}
{% assign newArray = newArray | push: newItem %}
{% endfor %}
The newArray now contains a list of altered items from thingy.foo.

Liquid filter collection where not null

In my front matter for some pages (not all) I have:
---
top-navigation:
order: 2
---
Using liquid I want to filter all site pages which have a top-navigation object and sort by top-navigation.order.
I'm trying sort:'top-navigation.order' but that's throwing an exception of undefined method [] for nil:NilClass. I tried where:"top-navigation", true but it's not equating truthy values.
How can I filter for pages that have top-navigation and then sort?
Two steps:
Create an array with pages that contains the top-navigation key.
We create an empty array and then push the items that have the key.
{% assign navposts = ''|split:''%}
{% for post in site.posts %}
{% if post.top-navigation %}
{% assign navposts = navposts|push:post%}
{% endif %}
{% endfor %}
Sort the above array by top-navigation.order
{% assign navposts = navposts|sort: "top-navigation.order"%}
Printing results:
{% for post in navposts %}
<br>{{ post.title }} - {{post.top-navigation}}
{% endfor %}
For pages use site.pages.
In Jekyll 3.2.0+ (and Github Pages) you can use the where_exp filter like so:
{% assign posts_with_nav = site.posts | where_exp: "post", "post.top-navigation" %}
Here, for each item in site.posts, we bind it to the 'post' variable and then evaluate the expression 'post.top-navigation'. If it evaluates truthy, then it will be selected.
Then, putting it together with the sorting, you'd have this:
{%
assign sorted_posts_with_nav = site.posts
| where_exp: "post", "post.top-navigation"
| sort: "top-navigation.order"
%}
Liquid also has the where filter which, when you don't give it a target value, selects all elements with a truthy value for that property:
{% assign posts_with_nav = site.posts | where: "top-navigation" %}
Unfortunately, this variant does not work with Jekyll.

Jekyll/liquid list parameter?

I wanted to create a simply include which simplifies creating a carousel. So I was looking for the syntax to give a list of image urls as a parameter. However I couldn't find anything about this.
{% include carousel.html images=WHAT HERE? %}
You can create a list as a string then convert it into an array inside your snippet. This is the way I would do it.
{% assign urls = 'url1.jpg,url2.jpg,url3.jpg' %}
{% include carousel.html images=urls %}
Of course this is the same as:
{% include carousel.html images='url1.jpg,url2.jpg,url3.jpg' %}
carousel.html
{% assign images = include.images | split: ',' %}
{% for image in images %}
{{ image }}
{% endfor %}