loop through a for statement using an if/else with nunjucks and json - 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......

Related

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

jekyll: Is it possible to use a page.variable, as an operator inside a conditional if statement?

JSON file in path: _data/integers.json which looks like this:
{
"100": [
{
"value": "true"
}
]
}
In Jekyll page:
---
integers:
- 100
- 200
---
What I'm trying to do:
{% assign json = site.data.integers %}
{% for integer in page.integers %} // loop
{% if json.{{ integer }}[0].value == "true" %} ... {% endif %}
{% endfor %}
e.g. use the {{ integer }} (aka page.integer[0]) as an operator inside the conditional statement.
Is there a method? ... asking for a friend.
If we keep your json and page.integers as is :
{% assign json = site.data.integers %}
{{ json | inspect }}
{% for integer in page.integers %}
{% comment %} Here we cast our integer to a string,
as json keys are strings
(100 | append:"" => "100")
{% endcomment %}
{% assign intAsStr = integer | append:"" %}
{% comment %} as a possible json[intAsStr] returns an array,
we retrieve the first and only element in it
{% endcomment %}
{% assign data = json[intAsStr].first %}
{% if data["value"] == "true" %}
<h1>We have a match on {{ intAsStr }}</h1>
{% endif %}
{% endfor %}
We can simplify a little with some refactoring
data/integers.json
{
"100": { "value": true }
}
jekyll page
---
integers:
- "100"
- "200"
---
{% assign json = site.data.integers %}
{{ json | inspect }}
{% for integer in page.integers %}
{% assign data = json[integer] %}
{% if data["value"] == true %}
<h1>We have a match on {{ integer }}</h1>
{% endif %}
{% endfor %}

Find object by id in an array of JSON objects with Twig

I am being passed an array that unfortunately I cannot restructure:
"options": [
{"name":"namea","text":"valuea"},
{"name":"nameb","text":"valueb"},
{"name":"namec","text":"valuec"},
{"name":"named","text":"valued"}
]
I need to be able to find the object with the name equal to namea, nameb, namec, etc. and then produce the appropriate text. I tried the following and few other variations of that but could not get it to work:
{% for item in event.options %}
{% if item.name == "nameb" %}
{{ item.text|capitalize }}
{% endif %}
{% endfor %}
Thanks in advance for any help.
Edit: I basically only have access to a text box to input HTML and Twig. I do not have access to framework, custom extensions, etc.
Edit: JSON with exact formatting:
{
"source": "TEST.COM",
"trigger": "test",
"options": [{
"name":"test_date",
"value":"31-05-2017"
},
{
"name":"test_number",
"value":"9081003"
},
{
"name":"test_test",
"value":"9asd003"
},
{
"name":"Name",
"value":"Todd"
},
{
"name":"test_other",
"value":"kslkjsfd"
},
{
"name":"test_help",
"value":"908sdf3"
}]
}
This is going to be very hacky either way (I feel the javascript way as mentioned in the comments would still be less hacky).
However as its multilined we could write a basic parser like thing (this is by no means bullet proof and fails if the content has a ", or the structure changes or whatever changes to be honest):
{# create an array of lines #}
{% set event = event|split('\n') %}
{# an array to hold our options #}
{% set options = [] %}
{# using a bool to track if we are inside the options part #}
{% set inOptions = false %}
{# this holds the name of the last name value we have passed #}
{% set currentKey = '' %}
{# go through each line #}
{% for line in event %}
{# if we are inside the options tag do our magic #}
{% if inOptions %}
{# check if the line starts with "name": and track the current key name #}
{# or check if it starts with "value": and set the current key to that value #}
{% if line matches '/"name":/' %}
{# split line on the double quotes and get the last bit #}
{% set currentKey = line|split('"') %}
{# cant get the array index piped in one go idk.. #}
{% set currentKey = currentKey[3] %}
{% elseif line matches '/"value":/i' %}
{% set currentValue = line|split('"') %}
{% set options = options|merge({(currentKey): currentValue[3]}) %}
{% elseif line matches '/\s*}]/' %}
{% set inOptions = false %}
{% endif %}
{% endif %}
{# check for the options sectioning start #}
{% if line matches '/^"options/' %}
{% set inOptions = true %}
{% endif %}
{% endfor %}
{{ dump(options) }}
This returns in my dump (which you didn't have so you cant see):
array:6 [▼
"test_date" => "31-05-2017"
"test_number" => "9081003"
"test_test" => "9asd003"
"Name" => "Todd"
"test_other" => "kslkjsfd"
"test_help" => "908sdf3"
]
As an actual array where you can then call options.test_date but all this is super hacky, it still can be improved but twig is not made for it and the syntax gets so clunky its hard to maintain.

Display JSON data with criteria in Jekyll

I have a JSON file with the following structure:
{
"resources": [
{
"date": "Nov 7",
"content": [
{
"articleTitle":"The Distribution of Users’ Computer Skills: Worse Than You Think",
"articleUrl":"https://www.nngroup.com/articles/computer-skill-levels/?ref=boomkrak",
"articleAuthor": "Jakob Nielson",
"articleTag": "ux, web design"
},
{
"articleTitle":"How to Use Animation to Improve UX",
"articleUrl":"https://uxplanet.org/how-to-use-animation-to-improve-ux-338819e93bdb#.84b3m022s?ref=boomkrak",
"articleAuthor": "Nick Babich",
"articleTag": "ux, animation"
}
]
},
{
"date": "Nov 15",
"content": [
{
"articleTitle":" 7 Things Every Designer Needs to Know about Accessibility",
"articleUrl":"https://medium.com/salesforce-ux/7-things-every-designer-needs-to-know-about-accessibility-64f105f0881b#.5pgg5014x?ref=boomkrak",
"articleAuthor": "Jesse Hausler",
"articleTag": "ux, web design, accessibility"
},
{
"articleTitle":"Get the most out of your research with storytelling",
"articleUrl":"https://blog.intercom.com/get-the-most-out-of-your-research-storytelling/?ref=boomkrak",
"articleAuthor": "Jillian Wells",
"articleTag": "design research, collaboration"
}
]
}
]
}
I want to show the article based on each tag. For example, if I want to show ux articles, then all articles with ux tag should be displayed.
Anyone know how to do it in Jekyll?
Considering that your datas are in _datas/articles.json, you can use this include file (_includes/listbyTag.html) :
{% assign tag = include.tag %}
{% assign days = site.data.articles.resources %}
{% assign list = ""| split: "/" %} {% comment %} creates an empty array {% endcomment %}
{% for day in days %}
{% for article in day.content %}
{% if article.articleTag contains tag %}
{% assign list = list | push: article %}
{% endif %}
{% endfor %}
{% endfor %}
{% if list.size != 0 %}
<h3>Found {{ list.size }} posts for tag : {{ tag }}</h3>
<ul>
{% for post in list %}
<li>{{ post.articleTitle }}</li>
{% endfor %}
</ul>
{% endif %}
Now you can include it anywhere with :
{% include listByTag.html tag="ux" %}
Or for a tag page :
---
tag: ux
title: my title
layout: default
---
{% include listByTag.html tag=page.tag %}

swig-template testing condition with subdocument

I have a json:
var json = [{
a: "asdf",
b: "a",
c: {1:{z:30,x:20,y:50},2:{z:30,x:50,y:30}}
},
{
a: "fdsa",
b: "o",
c: {1:{z:10,x:20,y:50},2:{z:0,x:20,y:30}}
}
]
I want to have a condition to check:
if any item z, x, or y in the c object is greater than 30, show the value for a
Is this possible? I did some research but couldn't find any answers.
Please help! Thanks!
I tried
{% for c,b in json.c %}
Your use case is incredibly complex and probably better done server-side, but here's a way you can do it in swig...
{% for item in json %}
{% set show = false %}
{% for set in item.c %}
{% for k in set %}
{% if k > 30 %}
{% set show = true %}
{% endif %}
{% endfor %}
{% endfor %}
{% if show %}
{{ item.a }}
{% endif %}
{% endfor %}