Using two JSON sources for Jekyll output - json

Suppose I have a list of projects (let's call that proj.json) and a list of smaller sub-projects (sub_proj.json) that are associated with the list of projects. The files are as follows:
proj.json
[{
"title": "Project 1",
"description": "aaa.",
"subproj": ["RefSP1", "RefSP2"]
},
{
"title": "Project 2",
"description": "aaa.",
"subproj": ["RefSP3"]
}]
sub_proj.json
[{
"title": "Sub Project 1",
"description": "aaa.",
"key": "RefSP1"
},
{
"title": "Sub Project 2",
"description": "aaa.",
"key": "RefSP2"
},
{
"title": "Sub Project 3",
"description": "aaa.",
"key": "RefSP3"
}]
But in the output.html, I seem to be missing something. The code is below: (I removed it of formatting for simplicity)
{% for item in site.data.proj %}
{{ item.title }}
{% assign key_array = item.subproj %}
{% for sub in key_array %}
{% assign subproject = site.data.sub_proj | where:"key",sub %}
{{ subproject.title | inspect }}
{% endfor %}
I seem to get the correct number of subprojects using {{ subproject.title | inspect }}, but they're all nil. Adding jsonify doesn't really do anything.
edit:
Printing out {{ item | inspect }}
results in
{ "title"=>"Project 1","description"=>"aaa.","subproj"=>["RefSP1","RefSP2"]}
But {{ subproject | inspect }}
comes out as
[{"title"=>"Sub Project 1","description"=>"aaa.","key"=>"RefSP1"}] [{"title"=>"Sub Project 2","description"=>"aaa.","key"=>"RefSP2"}]
The square brackets are the main difference. I tried removing them through filters, still nothing.

Related

filtering key and value of json data in jinja2

i have json file from url that i want to filter using jinja. The json file is loaded in my ansible as a variable "get_devices". Here is the json file :
{
"vni": {
"13": {
"192.168.13.2": {
"mac": "50:00:00:10:00:03",
"state": "active",
"type": "local"
},
"192.168.13.3": {
"mac": "50:00:00:05:00:03",
"remoteVtep": "10.0.0.6",
"state": "active",
"type": "remote"
},
"fe80::5200:ff:fe05:3": {
"mac": "50:00:00:05:00:03",
"remoteVtep": "10.0.0.6",
"state": "active",
"type": "remote"
},
"fe80::5200:ff:fe10:3": {
"mac": "50:00:00:10:00:03",
"state": "active",
"type": "local"
}
}
}
}
I'm new at using jinja, so the template might contain many mistakes and error. The template is like this :
{% for item in get_devices.json.results -%}
{% for key, value in item.vni.iteritems() %}
VNI Data
VNI Number : {{ key }}
{% for key, value in value.iteritems() %}
- IP : {{ key }}
{% for key, value in value.iteritems() %}
{{ value }}
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
And the expected result is like this :
VNI DATA
VNI Number : 13
- IP : 192.168.13.3
50:00:00:10:00:03
10.0.0.6
active
local
- IP : fe80::5200:ff:fe05:3
50:00:00:10:00:03
10.0.0.6
active
local
and so on. However, notice that some of the data don't have the remoteVtep so to keep the order of the resulting "values" in the same line, I want to replace remoteVtep with "-" if the data doesn't have remoteVtep. How to declare this in jinja2? This is an example of the desired output (of data that don't have remoteVtep):
- IP : 192.168.13.2
50:00:00:10:00:03
-
active
local
What changes are needed to achieve this? Thank you.

Jinja2 filter nested dictionary based on boolean value

I have the following dict variable users in Jinja2:
"users": {
"user1": {
"alive": true,
"age": 22
},
"user2": {
"alive": false,
"age": 34
}
}
and I want to filter all alive users with jinja filter, but after a long search I am still not able to achieve that on such nested structure. Could anyone please help?
For now, I am just passing all users with {{ users }}, but I guess it should be possible to filter it with built in Jinja filters. Just cannot figure out the right sequence of them.
users: {'user1': {'alive': True, 'age': 22}, 'user2': {'alive': False, 'age': 34}}
this j2 file does the job:
{% for user in users if users[user].alive %}
{{ user }}: {{ users[user] }}
{% endfor %}
result:
user1: {'alive': True, 'age': 22}

Can't get Image resource with tag

I want to display an image which is saved within a block schema.
To get the image the following tag should be created {{ mega_menu_block.settings.menu_image_1 }} and if I just insert this tag, everything works. The problem is that the number at the end should change to image_2 .. image 3 and so on. I have therefore created a capture tag like so:
{%- capture mega_menu_image_id -%}
mega_menu_block.settings.menu_image_{{ forloop.index }}
{%- endcapture -%}
But when I try to reference this like so: <img src="{{ mega_menu_image_id }}"> in my HTML, this won't work and it returns the following: <img src="//cdn.shopify.com/s/files/1/1264/0071/t/37/assets/mega_menu_block.settings.menu_image_1?3566">
This is my schema block code:
"blocks": [
{
"type": "mega_menu",
"name": "Mega menu",
"settings": [
{
"type": "text",
"id": "menu_item",
"label": "Menu item",
"info": "Enter menu item to apply a mega menu dropdown. [Learn more](https://support.maestrooo.com/article/180-navigation-enabling-and-configuring-mega-navigation)."
},
{
"type": "header",
"content": "images for menu title ex. \"iPhone opladere\"",
"info": "Add images for every header tag. Don't add more than there are tags."
},
{
"type": "image_picker",
"id": "menu_image_1",
"label": "Image",
"info": "600 x 400px .jpg recommended"
},
{
"type": "image_picker",
"id": "menu_image_2",
"label": "Image",
"info": "600 x 400px .jpg recommended"
},
{
"type": "image_picker",
"id": "menu_image_3",
"label": "Image",
"info": "600 x 400px .jpg recommended"
},
{
"type": "image_picker",
"id": "menu_image_4",
"label": "Image",
"info": "600 x 400px .jpg recommended"
},
What should I do to fix this reference?
Thank you!
I think you need to loop over the block and create the IMG link using img_tag
{% for block in section.blocks %}
{% for i in (1..4) %}
{% capture img %}menu_image_{{i}}{% endcapture %}
{ block.settings[img] | img_url: 'master' | img_tag }
{% endif %}
{% endfor %}

jinja2 template for loop idention error in json file

I'm trying to use a jinja2 template to render a json file. The structure is similar to:
"rows": [
{% for product in products %}
{
"id": {{ loop.index }},
"name": {{ product }},
"available": true
}{% if not loop.last %},
{% else %}
{% endif %}
{% endfor %}
],
[...]
The problem is that the output json is rendered as:
"rows": [
{
"id": {{ loop.index }},
"name": {{ product }},
"available": true
},
{
"id": {{ loop.index }},
"name": {{ product }},
"available": true
}
],
[...]
Note the bad indentation in the first { of each row. How can I solve this?
Thank you.
You can add a - to the Jinja2 enclosure to discard spaces in that direction:
{%- for product in products %}
Please read the documentation of Whitespace Control for details.

Why my v-for doesn't loop? VUE.JS with JSON

I'm loading the data coming from a .json but the v-for does not return a loop.
MY HTML:
<div id="app">
<template v-for="product in products">
<p>{{ product.brand }}</p>
<p>{{ product.images }}</p>
<p>{{ product.id }}</p>
<p>{{ product.title }}</p>
<p>{{ product.description }}</p>
<p>{{ product.price }}</p>
</template>
</div>
MY JS:
new Vue({
el: '#app',
data: {
products: []
},
methods: {
},
created: function() {
var self = this;
self.$http.get('http://localhost/app/products.json').then(function(response) {
self.products = response.body;
});
}
});
MY JSON:
"product": [
{
"brand": "Apple",
"images":"images/iphone-x-64-gb.jpg",
"id": "iphone-x-64-gb",
"title": "iPhone X 64 GB",
"description": "Lorem ipsum dolor",
"price": "1.159,00"
},
{
"brand": "Apple",
"images":"images/iphone-x-256-gb.jpg",
"id": "iphone-x-256-gb",
"title": "iPhone X 256 GB",
"description": "Lorem ipsum dolor",
"price": "1.329,00"
},
{
"brand": "Apple",
"images":"images/iphone-8-64-gb.jpg",
"id": "iphone-8-64-gb",
"title": "iPhone 8 64 GB",
"description": "Lorem ipsum dolor.",
"price": "819,99"
}
]
}
if I write in HTML like this dosen't work but if I put
{{ product[3].brand }} for example ... I can see only this one, just loop dosen't working.
Change your template to be something like the following...
<template>
<div class="wrapper">
<div v-for="product in products">
<p>{{ product.brand }}</p>
<p>{{ product.images }}</p>
<p>{{ product.id }}</p>
<p>{{ product.title }}</p>
<p>{{ product.description }}</p>
<p>{{ product.price }}</p>
</div>
</div>
</template>
Vue templates require a single root element between the <template> tags and also I believe v-for won't work properly on root element so I am nesting that in a "wrapper."
If you look in your dev tools console you probably will see an error that says something like.
Cannot use v-for on stateful component root element because it
renders multiple elements.
or
[Vue warn]: Multiple root nodes returned from render function.
Render function should return a single root node.
Additional
Also it appears you may have some other issues with your code. It seems to me your request should be like the following unless I am missing something about the way your json is being returned.
created: function() {
this.$http.get('http://localhost/app/products.json').then(function(response) {
this.products = response.body.products;
}.bind(this));
},
Notice the change from response.body to response.body.products Also it is fine to assign self to this but I find using .bind(this) more succinct.
Here is a working fiddle based on your code. https://jsfiddle.net/skribe/umx98rxm/