Accessing _data in Jekyll (loop in loop) - jekyll

Given this YAML:
- maincategory:
title: "Projects"
subcategory:
title: "General"
item:
title: "Alpha"
item:
title: "Beta"
- maincategory:
title: "Support"
subcategory:
title: "General"
item:
title: "Something"
item:
title: "Else"
How would one iterate over this data if the Jekyll _data file is called entries.yml?
So far I've gotten here but I'm not sure whether I should keep referencing the site.data oject in sub-loops. Also not sure whether this is even possible.
{% for entry in site.data.entries %}
<h2>{{ entry.maincategory.title }}</h3>
{% for subcategory in site.data.entries.maincategories %}
<h3>{{ entry.maincategory.subcategory.title }}</h3>
<ul>
{% for item in site.data.entries.maincategory.subcategories %}
<li>{{ item.title }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endfor %}
To be clear, this is where I want to end up (output wise):
<!-- Loop over every main category -->
<h2>Main category title</h2>
<!-- Loop over every sub category within main category -->
<h3>Subcategory title</h3>
<ul>
<!-- Loop over every item in this subcategory -->
<li>Item title
</li>

YAML:
- title: "Projects"
subcategories:
- title: "project-sub1"
items:
- title: "project-sub1-item1"
href: "#"
- title: "project-sub1-item2"
href: "#"
- title: "project-sub2"
items:
- title: "project-sub2-item1"
href: "#"
- title: "project-sub2-item2"
href: "#"
- title: "Support"
subcategories:
- title: "support-sub1"
items:
- title: "support-sub1-item1"
href: "#"
- title: "support-sub1-item2"
href: "#"
Nested loops:
{% for entry in site.data.entries %}
<h2>{{ entry.title }}</h2>
{% for subcategory in entry.subcategories %}
<h3>{{ subcategory.title }}</h3>
<ul>
{% for item in subcategory.items %}
<li>{{ item.title }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endfor %}
Output:
<h2>Projects</h3>
<h3>project-sub1</h3>
<ul>
<li>project-sub1-item1</li>
<li>project-sub1-item2</li>
</ul>
<h3>project-sub2</h3>
<ul>
<li>project-sub2-item1</li>
<li>project-sub2-item2</li>
</ul>
<h2>Support</h3>
<h3>support-sub1</h3>
<ul>
<li>support-sub1-item1</li>
<li>support-sub1-item2</li>
</ul>

Related

How to Sort Jekyll Post by Front Matter

how to sort posts by order in Jekyll liquid.
---
layout: post
title: my title
order: 1
---
From https://jekyllrb.com/docs/posts/
Sort
Sort an array. Optional arguments for hashes 1. property name 2. nils order (first or last).
Examples:
{{ page.tags | sort }}
{{ site.posts | sort: "author" }}
{{ site.pages | sort: "title", "last" }}
<ul>
{% for post in site.posts %}
<li>
{{ post.title }}
</li>
{% endfor %}
</ul>
From https://jekyllrb.com/docs/liquid/filters/:
{{ site.posts | sort: "author" }}
I think, this should do it:
<!-- or + last, see above -->
{% assign sorted_posts = site.posts | sort "order" %}
<ul>
{% for post in sorted_posts %}
<li>
{{ post.title }}
</li>
{% endfor %}
</ul>

How to create a drop down menu in yml using jekyll

I have code that displays buttons on navbar. On one of the buttons I would like to add a drop down menu. I've already added the code for the drop down in my navigation.yml file, but I am having issues adding it in my jekyll html file. Below is part of the code that shows the navigation bar with button links. I just need help adding the drop down menu code.
-----html file-----
<ul class="visible-links">
{%- for link in site.data.navigation.main -%}
<li class="masthead__menu-item">
<a href="{{ link.url | relative_url }}"{% if link.description %} title="{{ link.description }} "{% endif %}>{{ link.title }}</a>
</li>
{%- endfor -%}
</ul>
---navigation.yml file------
- title: "Contact Us"
sublinks:
- title: "Text goes here"
url: "#"
- title: "Text goes here"
url: "#"
- title: "Text goes here"
url: "#"
I'm not that familiar with Jekyll, so any help is needed.
Thanks,
See the menu.yml file
primary:
- title: Main Menu
subfolderitems:
- name: "Home"
url: "../"
weight: 2
- name: "Pages"
url: "#"
weight: 3
subsubfolderitems:
- name: "About"
url: "/about/"
weight: 2
- name: "Pricing"
url: "/pricing/"
weight: 2
- name: "Faq's"
url: "/faq/"
weight: 2
- name: "Contact"
url: "/contact/"
weight: 2
- name: "Testimonial"
url: "/testimonial/"
weight: 2
- name: "404"
url: "/404/"
weight: 2
- name: "Blog"
url: "#"
weight: 3
subsubfolderitems:
- name: "Blog Listing"
url: "/blog/"
weight: 2
- name: "Blog Single"
url: "/adum-software-industry-how-achive-the-goal/"
weight: 2
- name: "Contact"
url: "/contact/"
weight: 2
See the dropdown query file. You need to write some css style for the menu
<nav class="header-menu" id="header-menu">
{% if site.data.menus.primary[0] %}
{% for item in site.data.menus.primary %}
{% if item.subfolderitems[0] %}
<ul class="menu">
{% for entry in item.subfolderitems %}
<li class="{% if entry.subsubfolderitems[0] %}has-sub{% endif %} menu-item">
<a class="menu-link nav-link {% if entry.subsubfolderitems[0] %}menu-toggle{% endif %}" href="{{ entry.url }}">{{ entry.name }}</a>
{% if entry.subsubfolderitems[0] %}
<ul class="menu-sub menu-drop">
{% for subentry in entry.subsubfolderitems %}
<li class="menu-item">
<a class="menu-link nav-link" href="{{ subentry.url }}">{{ subentry.name }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
{% endif %}
</nav>

Loop unique values in nested data tree in Jekyll

I have a data files with different items. Each item have nested tasks. I am trying to loop the nested tasks and present each task by the task type.
YML DATA
- name: Outside
description: Description
tasks:
- type: Food
name: Eat it outside
status: working
- type: Drinks
name: Drink it outside
status: working
- name: Inside
description: Description
tasks:
- type: Food
name: Eat it inside
status: pending
- type: Drinks
name: Drink it inside
status: working
Liquid
{% for item in site.data.info %}
{% assign grouped-tasks-by-type = item.tasks | group_by: "type" %}
{% for task in grouped-tasks-by-type %}
<h2 class="task-type">{{ task.type }}</h2>
<ul>
{% for task in item.tasks %}
{% if task.status == 'working' %}
<li>{{ item.name }}: {{ task.name }}</li>
{% endif %}
{% endfor %}
</ul>
{% endfor %}
{% endfor %}
Expected result (HTML)
<h2 class="task-type">Food</h2>
<ul>
<li>Outside: Eat it outside<li>
</ul>
<h2 class="task-type">Drinks</h2>
<ul>
<li>Outside: Drink it outside<li>
<li>Inside: Drink it inside<li>
</ul>
However, I am getting a full blank result. Is this possible to do with group_by?
I hope my algorithm below serves you well. I was able to achieve your expect end result with the algorithm. I was unable to utilize the group_by in my solution. The sample code contains Liquid comment blocks to explain my thought process.
Testing
I used the minima git repo, with command jekyll s. I placed your YML data in a file with path _data/info.yml in my locally cloned minima git repo. I used post.html as the code sandbox.
You can print out the Liquid variables to the DOM by doing {{ all_food_types | json }} in the code.
Solution
{%- comment -%}
End Goal: Find all the food types for <h2>.
1. Use map: "tasks" to gather all the tasks into a single array.
This will cause the loss of Outside/Inside information for each task
2. Use map: "type" to create a list of food types ("Food", "Drinks")
3. Use uniq to remove duplicate food types from the array
{%- endcomment -%}
{% assign all_food_types = site.data.info | map: "tasks" | map: "type" | uniq %}
{%- comment -%}
End Goal: Loop through all the data looking
for a specific food type (Food, Drinks)
and group them together
{%- endcomment -%}
{% for food_type in all_food_types %}
<h2 class="task-type">{{ food_type }}</h2>
<ul>
{% for item in site.data.info %}
{% for task in item.tasks %}
{% if task.status == 'working' and task.type == food_type %}
<li>{{ item.name }}: {{ task.name }}</li>
{% endif %}
{% endfor %}
{% endfor %}
</ul>
{% endfor %}
An aside, for whatever reason, my liquid ends up using a lot of arrays and for-loops.

Grouping collection by category

I have the following collection in my jekyll project:
portfolio
|- portrait
|-- daniel.md
|-- george.md
|- nature
|-- national-park.md
|- food
|-- lasagna.md
|-- buritto.md
|-- pizza.md
What I want is to render a portfolio page grouping my portfolio by categories [ such as: portrait, nature and food ].
I've only managed to render my portfolio in one flat level like this:
<ul>
{% assign portfolio = site.portfolio %}
{% for entry in portfolio %}
<li class="item">
<h4 class="post-title">{{ entry.title }}</h4>
</li>
{% endfor %}
</ul>
I've found a solution. I've added the category name in front matter for each of the markdown files:
---
category: portrait
---
Then, I've changed my liquid to this:
{% assign category = site.portfolio | group_by: 'category' %}
{% for item in category %}
<!-- This is the category name -->
<h2>{{item.name}}</h2>
<ul>
<!-- filter the categories, selecting only the current category in the loop -->
{% assign portfolio = site.portfolio | where: 'category', item.name %}
{% for entry in portfolio %}
<li class="item">
<h4 class="post-title">{{ entry.title }}</h4>
</li>
{% endfor %}
</ul>
{% endfor %}
Is there any other way not to use front matter but the name of the folders inside my collection?

Jekyll, Liquid - get posts belonging to category1 and category2

I produced an overview page for all posts from the category "Tutorials" like this:
<ul class="post-list">
{% for post in site.categories.Tutorials %}
<li>
<span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}</span>
<h2>
<a class="post-link" href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a>
</h2>
{{ post.excerpt }}
</li>
{% endfor %}
</ul>
But now I would like to produce an index page for posts with both category "Tutorials" and category "German". But how?
The post I would like to have in this overview page is this one:
---
layout: post
title: 'German tutorial'
categories: [Tutorials, German]
---
Posts I would not like to have in this overview page are posts with a header like this:
---
layout: "post"
title: "English totorial"
categories: [Tutorials, English]
---
I tried for example:
{% for post in site.categories.Tutorials & site.categories.German %}
but this doesn't work...
I easily would switch to tags instead of categories, if this makes it easier.
Get the first category array : site.categories.Tutorials then sort German category posts out of it :
{% assign tutorials = site.categories.Tutorials %}
{% comment %}Creates an empty array{% endcomment %}
{% assign germansTutos = "" | split: "/" %}
{% for p in tutorials %}
{% if p.categories contains "German" %}
{% assign germansTutos = germansTutos | push: p %}
{% endif %}
{% endfor %}
<ul>
{% for post in germansTutos %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
You can also simply assign a tutorial category and a lang variable to your posts and filter them by the power of the where filter.
eg:
---
layout: post
title: "Post 1"
date: 2016-01-27 00:29:55 +0100
categories: Tutorials
lang: ge
---
Post one
You can then sort your posts like this :
{% assign tutorials = site.categories.Tutorials %}
{% assign germanTutos = tutorials | where: 'lang', 'ge' %}
<ul>
{% for post in germanTutos %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>