Ansible loops matching on array/dict_list - ansible

I have an array like so
our_domains:
- domain: www.example.com
urls:
- { path: '/' }
- { path: '/test1' }
- domain: www.example2.com
urls:
- { path: '/' }
- { path: '/test2' }
and in a template I want to match on a given domain and then loop over the contents of urls
e.g
{% if item.value.domain == 'www.example2.com' %}
{% for item_url in item.urls %}
service_description http://anotherwebsite.com{{ item_url['path'] }}
{% endfor %}
{% endif %}
Im sure the FOR loop will work ok as its working in a similar context elsewhere in the code.
Im just struggling getting a conditional match on the domain name.
Any help would be appreciated
Thanks

it looks like you want to execute the template task for each of the elements of the our_domains list.
you should just remove the value from the if statement, rest looks fine:
{% if item.domain == 'www.example2.com' %}
{% for item_url in item.urls %}
service_description http://anotherwebsite.com{{ item_url['path'] }}
{% endfor %}
{% endif %}
if on the other hand, your intention was to generate only 1 file, you should use this template (one more for loop added enclosing the previous code):
{% for item in our_domains %}
{% if item.domain == 'www.example2.com' %}
{% for item_url in item.urls %}
service_description http://anotherwebsite.com{{ item_url['path'] }}
{% endfor %}
{% endif %}
{% endfor %}

Related

How to pass a limit parameter to an include using Jekyll's Liquid

I have a collection of projects on my site that I iterate over using {% for project in site.projects %} and store in an include called projects-list.html.
I would like to include the latest project from this collection on the homepage as a ‘featured’ item – is it possible to include the projects-list but pass in a limit:1 parameter so that only the first project is shown? Based on the Jekyll docs found here, I have tried passing the parameter to the include like this:
{% for project in site.projects limit:{{ include.limit }} %}
and refercing the include like this:
{% include projects-list.html limit=1 %}
but this does not appear to work. Is this a syntax error or am I missing something?
You could try the first
{% assign projectFeatured = site.projects | first %}
{% for projects in site.projects %}
{% include projects-list.html %}
{% endfor %}
{% for projects in projectFeatured %}
{% include projects-list.html %}
{% endfor %}
Though I encourage you to add a featured: True in your post and do something like that:
{% if post.featured == true %}
{% include post.html %}
{% endif %}
https://shopify.github.io/liquid/filters/first/
Below is my current solution (with featured: true) added to post frontmatter. It's really nasty but appears to work for now:
<div class="project-list">
{% if page.layout == "home" %}
{% assign projects = site.projects | where: "featured", "true" %}
{% for project in projects %}
{% include project/project.html %}
{% endfor %}
{% else %}
{% assign projects = site.projects %}
{% for project in projects %}
{% include project/project.html %}
{% endfor %}
{% endif %}
</div>

How can I output social url's in JSON+LD from a yaml data file?

My code will capture items from the data file. I need those to be comma separated. I've had no luck!
Data File socialmedia.yml
facebook:
id: 'dpcgco'
href: 'https://www.facebook.com/'
title: 'Facebook'
fa-icon: 'fa-facebook-square'
twitter:
id: 'DenverProphitJr'
href: 'https://www.twitter.com/'
title: 'Twitter'
fa-icon: 'fa-twitter-square'
I have tried this. It doesn't comma separate them, though:
"sameAs":[
{% if site.data.socialmedia %}
{% assign sm = site.data.socialmedia %}
{% for entry in sm %}
{% assign key = entry | first | split%}
{% if sm[key].id %}
{% capture social %}{{ sm[key].href }}{{ sm[key].id }}{% endcapture %}
{{ social | replace: " ", "," | jsonify }}
{% endif %}
{% endfor %}
{% endif %}
],
Desired Output Format:
"sameAs": [
"http://www.facebook.com/your-profile",
"http://instagram.com/yourProfile",
"http://www.linkedin.com/in/yourprofile",
"http://plus.google.com/your_profile"
]
Actual Invalid Output:
"sameAs":[ "https://www.facebook.com/dpcgco" "https://www.twitter.com/DenverProphitJr" ],
You have to check if an item is the last in the forloop.last.
{% if site.data.socialmedia %}
{% assign sm = site.data.socialmedia %}
"sameAs":[
{% for entry in sm %}
{% assign key = entry | first %}
{% if sm[key].id %}"{{ sm[key].href }}
{{ sm[key].id }}",
{% if forloop.last %}
"{{ sm[key].href }}{{ sm[key].id }}"
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
],

'for' tag was never closed / if elsif else in liquid logic to include a page?

My Jekyll version is 3.8.6.
If I have too many elseif I get a for logic error where no for loop was written. If I remove one elseif, it works.
This does not work:
{% if page.jsontype == "page" %}
{% include pageJSONLD.html %}
{% elsif page.jsontype == "collection" %}
{% include collectionJSONLD.html %}
{% elsif page.jsontype == "post" %}
{% include postJSONLD.html %}
{% elsif page.jsontype == "about" %}
{% include aboutJSONLD.html %}
{% elsif page.jsontype == "lawyer" %}
{% include lawyerJSONLD.html %}
{% elsif page.jsontype == "contact" %}
{% include contactJSONLD.html %}
{% else %}
{% include homeJSONLD.html %}
{% endif %}
This Works!
{% if page.jsontype == "page" %}
{% include pageJSONLD.html %}
{% elsif page.jsontype == "post" %}
{% include postJSONLD.html %}
{% elsif page.jsontype == "about" %}
{% include aboutJSONLD.html %}
{% elsif page.jsontype == "lawyer" %}
{% include lawyerJSONLD.html %}
{% elsif page.jsontype == "contact" %}
{% include contactJSONLD.html %}
{% else %}
{% include homeJSONLD.html %}
{% endif %}
The error I get with the additional elsif is
Jekyll Feed: Generating feed for posts
Liquid Exception: Liquid syntax error (/home/xxxxx/repositories/legal/_includes/_head.html line 100): 'for' tag was never closed included in /_layouts/default.html
Error: Liquid syntax error (/home/xxxx/repositories/legal/_includes/_head.html line 100): 'for' tag was never closed included
Error: Run jekyll build --trace for more information.
Line: 100 is {% elsif page.jsontype == "lawyer" %}.
Edit 1:
I have got the same error when using case/when
{% case page.jsontype %}
{% when 'page' %}
{% include pageJSONLD.html %}
{% when 'collection' %}
{% include collectionJSONLD.html %}
{% when 'post' %}
{% include postJSONLD.html %}
{% when 'about' %}
{% include aboutJSONLD.html %}
{% when 'lawyer' %}
{% include lawyerJSONLD.html %}
{% when 'contact' %}
{% include contactJSONLD.html %}
{% else %}
{% include homeJSONLD.html %}
{% endcase %}
It still shows the same error pointing to the end of the head file.
In my tests with Jekyll 3.8.5 and Jekyll 4.0.0 both scenarios worked like a charm, no errors, no limitations:
If/else:
{% if page.jsontype == "page" %}
{% include 1.html %}
{% elsif page.jsontype == "collection" %}
{% include 2.html %}
{% elsif page.jsontype == "post" %}
{% include 3.html %}
{% elsif page.jsontype == "about" %}
{% include 4.html %}
{% elsif page.jsontype == "lawyer" %}
{% include 5.html %}
{% elsif page.jsontype == "contact" %}
{% include 6.html %}
{% else %}
{% include 7.html %}
{% endif %}
Case/When:
{% case page.jsontype %}
{% when 'page' %}
{% include 1.html %}
{% when 'collection' %}
{% include 2.html %}
{% when 'post' %}
{% include 3.html %}
{% when 'about' %}
{% include 4.html %}
{% when 'lawyer' %}
{% include 5.html %}
{% when 'contact' %}
{% include 6.html %}
{% else %}
{% include 7.html %}
{% endcase %}
Any missing {% endfor %}, also within the includes files, showed the same error message but the correct line:
Liquid Exception: Liquid syntax error (C:/Users/User/Desktop/ruby_projects/jekyll_test/testpage/_includes/3.html line 9): 'for' tag was never closed included in /_layouts/default.html
jekyll 3.8.6 | Error: Liquid syntax error (C:/Users/User/Desktop/ruby_projects/jekyll_test/testpage/_includes/3.html line 9): 'for' tag was never closed included
One of my last thoughts was that you added and removed a specific page, e.g. collectionJSONLD.html every time when testing this (as you confirmed).
There must be a specific thing we can't see as you haven't posted the complete code of the project. Nevertheless, great to read that you solved it! This was a hard one :)
The file collectionJSONLD.html was missing {% endfor %}
{% for member in site.data.members %}
{
"#type": "ListItem",
"name": "{{ member.name }}",
"url": "{{ member.permalink }}",
"position": "{{ forloop.index }}"
{% if forloop.first %}
},
{% elsif forloop.last %}
}
{% endif %}
{% endfor %}
],

Ansible jinja block

How to comment a particular line only by using jinja template.
I have my line
/var/log/maillog
I have tried
{% comment %}{{ var }} {% endcomment %}
also
{% if var is defined %}
{{ var }}
{% endif %}
Can you try this:
{# {{ var }} #}

Why doesn't this Jekyll Liquid where filter filter?

I am trying to output a list of blog posts for a certain author. I tried this where Jekyll filter:
{% for post in (site.posts | where:"author", "mike") %}
{{ post.title }}
{% endfor %}
But it outputs every post. I'm not clear what I'm doing wrong.
Supposing that your post author is in your front matter, like this :
---
author: toto
...
---
If you want two last post by author == toto, just do :
{% assign counter = 0 %}
{% assign maxPostCount = 2 %}
<ul>
{% for post in site.posts %}
{% if post.author == 'toto' and counter < maxPostCount %}
{% assign counter=counter | plus:1 %}
<li>{{ counter }} - {{ post.title }}</li>
{% endif %}
{% endfor %}
</ul>
Et hop !
EDIT :
And another solution using the where filter instead of the if clause :
{% assign posts = site.posts | where: "author", "toto" %}
{% assign counter2 = 0 %}
{% assign maxPostCount2 = 3 %}
<ul>
{% for post in posts %}
{% if counter2 < maxPostCount2 %}
{% assign counter2=counter2 | plus:1 %}
<li>{{ counter2 }} - {{ post.title }}</li>
{% endif %}
{% endfor %}
</ul>
RE-EDIT: Justin is right I don't need my two vars (counter2 and maxPostCount2), I can use Liquid for loop limit:n option.
{% assign posts = site.posts | where: "author", "toto" %}
<ul>
{% for post in posts limit:3 %}
<Ol>{{ post.title }}</ol>
{% endfor %}
</ul>
Better !
You need to do an assign first for the filtered items
{% assign posts = site.posts | where:"author", "mike" %}
{% for post in posts %}
{{ post.title }}
{% endfor %}
It seems filters are to be used only inside output tags (those surrounded by {{ and }}. Which mean you could use something like :
{{ site.posts | where "author", "mike" }}
But you can't use it the way you're doing.
Source: liquid documentation on Filters

Resources