Encoding JSON in a GitHub Pages generated file - jekyll

I'm attempting to create a JSON feed on a GitHub Pages site, and I'm having issues with JSON because I'm not sure how I can properly encode it using Jekyll. Is there an extension or method I can use?
feed: http://iowacodecamp.github.io/sessions.json
source: https://github.com/IowaCodeCamp/iowacodecamp.github.io/blob/master/sessions.json
Note the double quotes in the data.

Your json doesn't validate because of the coma after the last session.
If you don't want a coma after the last session, use forloop liquid object around
{
"sessions": {
"session": [{% for session_hash in site.data.sessions %}{% assign session = session_hash[1] %}
{
"title": {{ session.title | jsonify }},
"description": {{ session.description | jsonify }},
"level": {{ session.level | jsonify }},
"author": {
"name": {{ session.speaker.name | jsonify }},
"slug": {{ session.speaker.slug | jsonify }}
}
}{% if forloop.last == false %}, {% endif %}{% endfor %}
]
}
}
Question : You have multiples sessions in your datas but they are all in the same session array. Do you really need this key ? Maybe you can just do :
{
"sessions": [{% for session in site.data.sessions %}
{{ session[1] | jsonify }}{% if forloop.last == false %}, {% endif %}{% endfor %}
]
}
Which also validates.

I found a list of filters in the documentation: http://jekyllrb.com/docs/templates/
Proper usage is:
{{ session.description | jsonify }}

Related

How can I fetch a value from a JSON dictionary?

I am trying to grab the value green from the below JSON data dictionary.
The API endpoint located at http://localhost:9200/api/status give the below data:
{
"name":"prod01",
"uuid":"3430c40-e786-4325-bc48-e0a096956000",
"version":{
"number":"7.17.0",
"build_hash":"60a9838d21b6420bbdb5a4d07099111b74c68ceb",
"build_number":46534,
"build_snapshot":false
},
"status":{
"overall":{
"since":"2023-02-13T22:47:05.381Z",
"state":"green",
"title":"Green",
"nickname":"Looking good",
"icon":"success",
"uiColor":"secondary"
},
"statuses":[
{
"id":"core:elasticsearch#7.17.0",
"message":"Elasticsearch is available",
"since":"2023-02-13T22:47:05.381Z",
"state":"green",
"icon":"success",
"uiColor":"secondary"
},
{
"id":"core:savedObjects#7.17.0",
"message":"SavedObjects service has completed migrations and is available",
"since":"2023-02-13T22:47:05.381Z",
"state":"green",
"icon":"success",
"uiColor":"secondary"
}
]
}
}
And the test.sls file doing the job is:
{% set json_data = salt.cp.get_url('http://localhost:9200/api/status', dest=None) | load_json %}
{% for key, value in json_data.items() %}
{% if value['state'] == 'green' %}
{{ key }}: {{ value }} (found)
{% else %}
{{ key }}: {{ value }}
{% endif %}
{% endfor %}
Executing it, I get the error:
Rendering SLS 'base:svr.salt.dev.test' failed: Jinja variable 'str object' has no attribute 'state'
You are looping on all the key-value pairs of the object json_data, with json_data.items(), so, you do not have a my_dictionary['state'] anymore, what you have is a key which will be state and its value will be green.
This said, your {"state": "green"} is not in the root of your dictionary, so you will never find any key-value pair matching what you need.
What you can do, though is:
{% if load_json.status.overall.state == 'green' -%}
state: {{ load_json.status.overall.nickname }}
{% endif %}
Which would yield:
state: Looking good

loop through a for statement using an if/else with nunjucks and json

I'm trying to loop through a nested json file with nunjucks, give each object type a specific layout and sort all based on date.
So in my case I have two collections events and videos. Both collections will have an array of events and videos.
My file is named /content.json and structured as followed:
{
media: {
events: [
{
content_id: "1",
content_type: "event",
date: "01-11-2019",
etc: "etc"
},
{
content_id: "2",
content_type: "event",
date: "01-08-2019",
etc: "etc"
}
],
videos: [
{
content_id: "3",
content_type: "video",
date: "01-12-2019",
etc: "etc"
},
{
content_id: "4",
content_type: "video",
date: "01-09-2019",
etc: "etc"
}
]
}
}
I have tried to get the different object assigned with an if/else statement and then use a for loop to cycle through the array, but that has failed, see below:
{% for item in content.media %}
{% if item == events %}
{% for item in content.media.events %}
{% include "components/event.njk" %}
{% endfor %}
{% elif item == video %}
{% for item in content.media.videos %}
{% include "components/video.njk" %}
{% endfor %}
{% endif %}
{% endfor %}
I never got to try and sort all the content by date, but I have found:
{% for item in items|sort(attribute='date')%}
Can anyone guide me in right direction?
Thanks in advance.
AENM
This code outputs separated feeds by type of elements (event or video).
{% for event in content.media.events | sort(attribute = 'date') %}
{% include "components/event.njk" %}
{% endfor %}
{% for video in content.media.videos | sort(attribute = 'date') %}
{% include "components/video.njk" %}
{% endfor %}
If you need to output a mixed feed, you should join arrays to one and run trought it (fortunately each elements already have the type):
{% for item in [].concat(content.media.events, content.media.videos) | sort(attribute = 'date') %}
{% include "components/" + item.content_type + ".njk" %}
{% endfor %}
Aikon,
I got it now!!
It was another typo, you switched the media and events. (did you try to keep me sharp?! :-))
But that's why the concat didn't work!!
So this is the final working result:
{% for item in [].concat(media.content.events, media.content.videos) | sort(attribute = 'date') %}
{% include "components/" + item.type + ".njk" %}
{% endfor %}
Only the date is not in the correct order, but I think that has to with my grid setup.
Thanks for helping me out......

Iterate array object in liquid template

I have a problem when my Liquid template iterate in array object. I want to transform an input json into another output json.
It is my Liquid Template:
{% assign clientList = Clients.value %}
{
"value": [
{% for client in clientList %}
{
"ACCOUNTNUM": "{{client.ACCOUNTNUM}}",
"EMAIL": "{{client.EMAIL}}",
"NAME": "{{client.NAME}}",
"PHONE": "{{client.PHONE}}",
"VATNUM": "{{client.VATNUM}}",
"RECID": "{{client.RECID}}",
"CANALID": "{{client.CANALID}}",
"CANALDESC": "{{client.CANALDESC}}"
}
{% if forloop.Last == false %}
,
{% endif %}
{% endfor %}
]
}
It is an input json example:
{
"Clients":{
"value":[
{
"#odata.etag":"",
"ItemInternalId":"3a93f2aa-dd77-4297-88c4-13241343321",
"ACCOUNTNUM":"01",
"EMAIL":"info#example.es",
"LANGUAGEID":"es",
"NAME":"Lili S.A.",
"PHONE":"943444666",
"VATNUM":"A01",
"DATAAREAID":"tr2",
"RECID":1412,
"DATAAREAID_x0023_2":"tr2",
"DATAAREAID_x0023_3":"tr2",
"CANALID":"C0010",
"CANALDESC":"Group gg"
},
{
"#odata.etag":"",
"ItemInternalId":"3a23f2aa-dd77-4297-88c4-13241343321",
"ACCOUNTNUM":"02",
"EMAIL":"info#example.es",
"LANGUAGEID":"es",
"NAME":"Lili2 S.A.",
"PHONE":"943444656",
"VATNUM":"A02",
"DATAAREAID":"tr2",
"RECID":1412,
"DATAAREAID_x0023_2":"tr2",
"DATAAREAID_x0023_3":"tr2",
"CANALID":"C0011",
"CANALDESC":"Group2 gg"
}
]
}
}
When I have launched my Logic App I got this error:
{\"StatusCode\":400,\"ErrorCode\":18,\"Details\":null,\"Message\":\"An error occurred while converting the transformed value to JSON. The transformed value is not a valid JSON. 'After parsing a value an unexpected character was encountered: :. Path 'print1', line 5, position 11.'\"
According to some test, it should be caused by the part shown as below in your liquid:
{% if forloop.Last == false %}
,
{% endif %}
I removed this part and the liquid map works fine, here I post my liquid map below for your reference:
{
"value": [
{% for client in content.Clients.value %}
{
"ACCOUNTNUM": "{{client.ACCOUNTNUM}}",
"EMAIL": "{{client.EMAIL}}",
"NAME": "{{client.NAME}}",
"PHONE": "{{client.PHONE}}",
"VATNUM": "{{client.VATNUM}}",
"RECID": "{{client.RECID}}",
"CANALID": "{{client.CANALID}}",
"CANALDESC": "{{client.CANALDESC}}"
},
{% endfor %}
]
}
Don't worry about the last "," because the "Transform JSON to JSON" action will deal with it. In the output of the "Transform JSON to JSON" action, it will not show an extra "," at the end of the json.

Why is this Jinja code adding an empty line when I use it to deserialize json data

Here is the code that I am using in ansible.
I am at beginner level so please forgive me if my question is naive
{% for item in results.response %}
{% for value in item.values() %}{{ value }}{% if not loop.last %},{% endif %}{% endfor %}
{{'\n'}}
{% if not loop.last %},{% endif %}
{% endfor %}
Here is the data format and the output (no match data to format , I just grabbed two random sections of the stdout and the output file
Data
results.response [
{
"address": "10.224.1.61",
"age": "32",
"interface": "GigabitEthernet9/7",
"mac": "cc16.7eec.1100",
"type": "ARPA"
},
{
"address": "10.70.0.150",
"age": "-",
"interface": "GigabitEthernet9/4",
"mac": "001d.7151.a400",
"type": "ARPA"
},
{
"address": "10.224.33.51",
"age": "-",
"interface": "TenGigabitEthernet2/2",
"mac": "001d.7151.a400",
"type": "ARPA"
},
{
"address": "10.224.32.51",
"age": "-",
"interface": "TenGigabitEthernet2/3",
"mac": "001d.7151.a400",
"type": "ARPA"
}
]
Output
,device1,FastEthernet6/0/0,-,ARPA,001d.7151.a400,171.255.50.133
,device1,FastEthernet6/0/0,132,ARPA,84b2.61a7.3a20,141.255.50.134
,device1,FastEthernet6/0/1,-,ARPA,001d.7151.a400,131.1.9.233
,device1,FastEthernet6/0/1,32,ARPA,0013.c446.2d91,101.1.9.234
,device1,GigabitEthernet5/1,-,ARPA,001d.7151.a400,110.1.15.174
,device1,GigabitEthernet5/1,140,ARPA,c471.feeb.a080,110.1.52.173
,device1,Vlan112,-,ARPA,001d.7151.a400,120.224.40.114
c.f. the Jinja2 docs here
You can also strip whitespace in templates by hand. If you add a minus sign (-) to the start or end of a block (e.g. a For tag), a comment, or a variable expression, the whitespaces before or after that block will be removed:
{% for item in seq -%}
{{ item }}
{%- endfor %}
Your code has both implied and explicit newlines.
{% for value in item.values() %}{{ value }}{% if not loop.last %},{% endif %}{% endfor %}
{{'\n'}}
Take that {{'\n'}} line out and try it. You could also organize it visually with manual space management. Watch the dashes by the percent signs -
{% for item in results.response -%}
{%- for value in item.values() -%}
{# keep none of the spacing aaround this value #}
{{ value }}{%- if not loop.last %},{% endif -%}
{# keep none of the spacing at the end the if #}
{%- endfor %}
{# KEEP the spacing at the end of each inner iteration #}
{% endfor %}
Will try to test this when I can get to a server.
Give me a bit.

How can I access JSON identifiers from Twig?

These are my JSON data:
[
{
"name":"unit 1",
"lessons":{
"1":{
"name":"lesson 1",
"content":"......."
},
"2":{
"name" "lesson 2",
"content":"......."
}
}
]
I can access these data using the following Twig code:
{% for unit in units %}
{{ unit.name }}
{% for lesson in unit.lessons %}
{{ lesson.name }}
{% endfor %}
{% endfor %}
But I want to access the lesson number, to make a hyperlink to the content. How can I do that?
You can Iterating over Keys and values as example:
{% for key, lesson in unit.lessons %}
{{ key}}
{{ lesson.name }}
{% endfor %}
Hope this help