How can I fetch a value from a JSON dictionary? - json

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

Related

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......

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

django not able to access jsonfield data in templates

Actually, I don't know how to access jsonfield data in the template. I tried something like this
{% for key in place.places_to_visit %}
{{ key }}:{{ value }}
{% endfor %}
But it is showing all json data that I have added including {} and " " and also same for Arrayfield of characters
I also want to add an image in that jsonfield, how to do that? Does that image need to be media directory and then I should include its path? Or some other ways to do that?
It is also showing error as follows
"[05/Sep/2017 23:03:00] "GET /ontheway/1/ HTTP/1.1" 200 4238"
jsonfield data of places_to visit is
"Places to visit": [
{
"name" : "some name",
"overview" : " some data",
"iamge": "image path"
}
{
"name" : "some name",
"Overview": " some data",
"image": "image path"
}
]
Thank you in advance
you can try to use items:
{% for data in place.places_to_visit %}
{% for key, value in data.items %}
{% if key == 'image' %}
<img src="{{ value }}">
{% else %}
<div> {{ key }}:{{ value }} </div>
{% endif %}
{% endfor %}
{% endfor %}

Encoding JSON in a GitHub Pages generated file

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 }}

How to access sub level JSON trough Django

So, I get this JSON from Django:
{'something' :
{'value':'somethingName','editable':'false'}
},
{'somethingElse':
{'value':'somethingElseName','editable':'true'}
}
And show it like this:
{% for key, value in obj.items %}
{{ key }} : {{ value }}
{% endfor %}
The problem is {{ value }} returns {'value':'somethingName','editable':'false'}, and I can't access value or editable trough {{ value.value }} or {{ value.editable }}.
I'd like to show {{ value.value }} as somethingName instead of the entire JSON.
Is there a way to access 'sub-level' JSON trough Django itself?
You cannot use template variable name as a dictionary key using the . notation. The second value in value.value is not interpreted as a string value because you have a variable name value in the loop.
Just rename key and value to obj_key and obj_value respectively:
{% for obj_key, obj_value in obj.items %}
{{ obj_key }} : {{ obj_value.value }}
{% endfor %}
Demo:
>>> from django.template import Context, Template
>>> t = Template("""
... {% for obj_key, obj_value in obj.items %}
... {{ obj_key }} : {{ obj_value.value }}
... {% endfor %}""")
>>> obj = {'something' : {'value':'somethingName','editable':'false'}}
>>> t.render(Context({'obj': obj}))
u'something : somethingName'
Hope that helps.