Can I create an runtime-array with values somehow? - arrays

I am trying to create a sidebar-menu that looks like this.
iOS
-entry1
-entry2
-entry3
Web
-entry1
-entry2
Other
-entry1
-entry2
Each "post" (as in - the files in the dir "_posts") will have one (or more) categories in the meta-data (at the top of the file) and is to be listed underneath that header in the menu. So for example, if I make a post which has got "categories: iOS" it should be listed under the "iOS" header in the menu.
{% for cat in ["jekyll","ios","test"] %} // This is what I am unable to get right
{% for post in site.posts %}
{% if post.category == cat %}
{{ post.categories }} // test
<li>{{ post.title }}</li>
{% endif %}
{% endfor %}
{% endfor %}
Is it not possible to create an array on the fly like this? I am finding it really hard to google this specific question I have.

Alright to create an array on the current page I needed to use "front matter" i.e. the things on top of the pages surrounded by "---"
This is the solution:
Top of page:
---
cats: [1,2,3,asd]
---
Further down:
{% for c in page.cats %}
{{c}}<br/>
#loop through more here.
{% endfor %}
</body>

Related

Fail dbt run based on Query Result

I am trying to run a procedure using Custom Macro. The Macro run the SQL(Call Statememnt) present in the Model sql file.
I am able to run the procedure but my objective is to capture the response of the procedure and fail the dbt run if response is 'Failure'. The procedure can return string 'Success' or 'Failure'.
I am able to capture the return but not sure how to explicitly fail the run based on the return value.
Macro:
{% materialization call_proc, adapter='snowflake' -%}
{% set query %}
use schema "{{ database }}"."{{ schema }}"
{% endset %}
{% do run_query(query) %}
{%- call statement('main',fetch_result=True) -%}
{{ sql }}
{%- endcall -%}
{% if execute %}
{%- set QRY_RSLT = load_result('main')['data'][0][0] -%}
{{log (QRY_RSLT)}}
{% endif %}
{{ return({'relations': []}) }}
{%- endmaterialization %}
Model SQL:
{{ config(
materialized='call_proc',
database='TEST_DB',
schema = 'TEST'
)
}}
call "{{ database }}"."{{ schema }}".TEST_PROC('TEST');
Checking the QRY_RSLT in logs I can see Success/Failure being printed. How to fail the model if 'Failure' is returned by Proc?
As I mentioned in my other answer, I don't think it's a good idea to use a custom materialization to call a stored procedure. You're better off using a macro for this.
But putting that aside, you can raise an exception using jinja:
{% if execute %}
{%- set QRY_RSLT = load_result('main')['data'][0][0] -%}
{% if QRY_RSLT == "failure" %}
{{ exceptions.raise_compiler_error("Invalid `QRY_RESULT`. Got: " ~ QRY_RSLT) }}
{% endif %}
{% endif %}

Jinja2 - If condition & nested array

I'd like to build to simple if logic into my Jinja2 template with nested arrays.
Firstly, including my vars for reference.
In YML (from host_vars):
interfaces:
- name: ae10
ipv4:
- address: 4.4.4.4
mask: 8
in JSON (from Ansible debug):
"interfaces": [
{
"ipv4": [
{
"address": "4.4.4.4",
"mask": 8
}
],
"name": "ae10"
}
],
I would like the if statement to make sure that ipv4.address and ipv4.mask have values. The only way I seem to be able to do it at the moment, is to map the nested array first, and then run if statement. But I'm wondering if the if statement can be ran earlier? Like even before the for loop starts?
{%for interface in interfaces%}
{%for ip in interface.ipv4%}
{% if ip.address and ip.mask%}
matched {{ip.address}}/{{ip.mask}} on {{interface.name}}
{% else %}
nothing matched
{% endif %}
{%endfor%}
{%endfor%}
It might, or might not be possible - and I might be missing something silly. Your thoughts would be greatly appreciated.
Q: "Can the if statement be run earlier? Like even before the for loop starts?"
A: No. It's not possible. It's possible to omit items that don't comply with the conditions, create a new dictionary, and process the new dictionary.
The task below is testing in the loop
- debug:
msg: "matched {{ item.1.address }}/{{ item.1.mask }} on {{ item.0.name }}"
loop: "{{ interfaces|subelements('ipv4') }}"
when:
- item.1.address is defined
- item.1.mask is defined
gives
"msg": "matched 4.4.4.4/8 on ae10"
Conditional output can be achieved also with the template below
{% for item in interfaces %}
{% for ip in item.ipv4 %}
{% if ip.address and ip.mask%}
matched {{ ip.address }}/{{ ip.mask }} on {{ item.name }}
{% else %}
nothing matched
{% endif %}
{% endfor %}
{% endfor %}

Print whitespace within jinja loop

I am trying to print the list of hosts in an ansible task;
I want to have spaces among them, however the following loop does not achieve the purpose:
{% for host in groups['all'] -%} {{ host }}:6379 {%- endfor %}
Any suggestions?
If you're aiming to get them all on a single line and don't mind having a space at the start you could simply do:
{% for host in groups['all'] -%} {{ ' ' ~ host }}:6379 {%- endfor %}
You could also add a character to the end of each item (e.g space or something else), while skipping the last one. Note the space between the if and endif:
{% for host in groups['all'] -%}
{{ host }}:6379
{%- if not loop.last %} {% endif %}
{%- endfor %}
As an alternative to the jinia loop, you could use ansibles join-filter, see in https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#id8
in this case :
{{ groups["all"] | join(":6379 ") }}
Join is the opposite for split. split takes a string and a delimiter and then return a list. join takes a list and a string to concatenate all list-elements to one string.

How to sort YAML using Jekyll Liquid

I have the following YML code that I am trying to sort alphabetically in Jekyll:
layout: project
title: Home renovation
link: http://urlgoeshere.com
builtWith:
- Concrete
- Glass
- Brick
- Dirt
Here is my template code:
<h4>Built With</h4>
<ul class="list-unstyled list-inline list-responsibilities">
{% for item in page.builtWith %}
<li>{{ item }}</li>
{% endfor %}
</ul>
What do I need to add to the for loop to get the builtWith items to sort alphabetically?
Thanks!
Try this
{% assign sorted = (page.builtWith | sort) %}
{% for item in sorted %}
In the latest Jekyll version, using just sort tag doesn't work because you need to assign it to a variable first: Liquid Warning: Liquid syntax error (line 24): Expected end_of_string but found pipe in "item in page.builtWith | sort".
If you are not using the latest version then it can work adding sort in the same line.
Using assign and sort tags is safer:
<h4>Built With</h4>
<ul class="list-unstyled list-inline list-responsibilities">
{% assign sorted = page.builtWith | sort %}
{% for item in sorted %}
<li>{{ item }}</li>
{% endfor %}
</ul>
Outputs:
Built With
Brick
Concrete
Dirt
Glass

collections pages loop not working on github

Jekyll Version: 2.4.0
github pages Version: 35
My Reproduction Steps
Build on locally and the looping of collections site.collections.guides.docs shown, generated the correct .html in _site folder as well.
However, when I deploy to github, it doesn't show the loop content.
The Output I Wanted
shown the loop in github pages, appreciate if someone have a look on my repo.
my codes:
// index.html
{% for doc in site.collections.guides.docs %}
{{ doc.content }}
{% endfor %}
// _config.yml
collections :
guides:
output: true
I would write it like this:
{% for doc in site.guides %}
{{ doc.content }}
{% endfor %}
And the config like this:
collections:
guides:
output: true

Resources