I have a list of courses to take using this courses.yml
- title: Basic Residential HSI Install
code: OSP0000111
description: Install and Repair residential and business class POTS, HSI, and Video services
newhire: true
skillset: Copper
jobtype: CST
advanced:
- title: PTA Testing Overview
code: OSP0000114
description: Teaches the technician how to close out a T1 test using the PTA system
newhire: false
skillset: Systems
jobtype: CO
advanced: no
- title: Technician Billing
code: OSP0000112
description: Teaches the technician how to properly bill the customer
newhire: false
skillset: Copper
jobtype: CST
advanced: yes
- title: Central Office Jumper
code: OSP0000113
description: Teaches the technician how to run jumpers
newhire: true
skillset: Copper
jobtype: CO
advanced: no
and I list the courses using:
<ul>
{% for teds in site.data.courses %}
<li> Course Title: {{ teds.title }} <br />
Course Code: {{ teds.code}} <br />
Course Description: {{ teds.description }}
</li>
{% endfor %}
</ul>
This works just fine. However, now I want to create a list using the same data file, of only those courses where the newhire variable is "true".
I have not understood any previous document that explains how to do this. I've tried a where clause and filter to no avail.
Any ideas?
Per https://jekyllrb.com/docs/templates/ website, I tried adding the where clause:
<ul>
{% for new in site.data.courses | where "newhire","true" %}
<li> Course Title: {{ new.title }} <br />
Course Code: {{ new.code }} | Job Type: {{ new.jobtype }} <br />
Description: {{ new.description }} <br />
Schedule
<hr />
</li>
{% endfor %}
</ul>
I refreshed the page and nothing happened. I got the same page, a list of ALL the courses. No filtering. I even restarted Jekyll server. Same result, no filtering.
No errors where noted by the Jekyll server either.
Per your answer, I changed the data file variables. 2ea "0's", 2ea "1's". Then I changed the html file to:
<ul>
{% assign teds = site.data.courses | where: 'newhire', 1 | sort: 'title' %}
{% for teds in courses %}
<li> Course Title: {{ teds.title }} <br />
Course Code: {{ teds.code }} <br />
Course Description: {{ teds.description }}
</li>
{% endfor %}
</ul>
The Jekyll server reported no errors but, when I refreshed the page, it displayed none of the data at all. No list of 4 titles, nor 2 liked I hope, just the web page. :(
UGGH, I saw my error when i reviewed it after dinner :)
Here's what worked:
<ul>
{% assign new = site.data.courses | where: 'newhire', 1 | sort: 'title' %}
{% for teds in new %}
<li> Course Title: {{ teds.title }} <br />
Course Code: {{ teds.code }} <br />
Course Description: {{ teds.description }}
</li>
{% endfor %}
</ul>
UGGH, I saw my error when i reviewed it after dinner :) A clear head helps!
The correct code was:
<ul>
{% assign new = site.data.courses | where: 'newhire', 1 | sort: 'title' %}
{% for teds in new %}
<li> Course Title: {{ teds.title }} <br />
Course Code: {{ teds.code }} <br />
Course Description: {{ teds.description }}
</li>
{% endfor %}
</ul>
Thank you so much, Christian!!
JOE
I can show you a working example from my blog, where I'm doing something similar like you want to achieve.
I think I tried it with true/false in the beginning, but I didn't get it to work, so I used 0/1 instead.
Here's the example:
I have a data file with projects. Each project has a sidebar property which is 0 or 1:
- name: Bitbucket Backup
url: /bitbucket-backup/
logo: /php/cache/img/bitbucket-backup-logo128x128.png
desc: A backup tool which clones all your Bitbucket repositories to your local machine
sidebar: 1
In my layout file, I have a sidebar where I only want to list those projects with sidebar == 1. I'm doing this with the following code:
{% assign projects = site.data.projects | where: 'sidebar', 1 | sort: 'name' %}
{% for project in projects %}
<li>{{ project.name }}</li>
{% endfor %}
Please note that it only works for me when I assign the line with the where clause to a variable (projects) and then loop the variable.
The following does not work:
{% for project in site.data.projects | where: 'sidebar', 1 | sort: 'name' %}
<li>{{ project.name }}</li>
{% endfor %}
Related
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.
As you see below, this is a fairly simple collection setup with an unordered lists of events that live in the _events folder at the root level (output is set to false). Instead of using {{ page.title }} in the layout, I want the heading(s) to read as months.
For example, if I add a new item into the _events collection and include month: January in the front-matter, I want that to generate a “January” heading, and place that unordered list underneath the heading. Likewise, if I add a new collection item and include month: February in the front-matter, I want to generate a “February” heading with a new unordered list below that heading.
I know I need a bit of re-arranging of where the heading lives, and I'm thinking I need some type of if statement, but I’m at a roadblock. I can’t figure this one out.
Is this possible with Jekyll Collections?
Layout
{% include root.html %}
<div class="flex-main">
{% include header.html %}
<main class="o-main" role="main">
<div class="o-grid-six">
<h1 class="f1 o-grid-six__child c-headline">{{ page.title }}</h1>
</div>
{{ content }}
</main>
</div>
<div class="flex-footer">
{% include footer.html %}
</div>
View (Events)
---
layout: events
title: Events
order: 2
---
<ul class="c-event-list">
{% for events in site.events %}
<li class="c-event-list__flag">
<div class="c-event-list__flag--left">
<div class="c-event-list__calendar">
<span class="c-event-list__day">{{ events.weekday }}</span>
<span class="f2 c-event-list__date">{{ events.date-number }}</span>
</div>
<img class="c-event-list__image" src="{{ p.url | prepend: site.baseurl }}{{ events.thumb }}" alt="">
</div>
<div class="c-event-list__flag--body">
<div class="c-event-list__content">
<h3 class="f2 c-event-list__title">{{ events.title }}</h3>
<p>{{ events.description }}</p>
<a class="c-button u-mt-2" href="{{ events.link }}">Sign Up</a>
</div>
</div>
</li>
{% endfor %}
</ul>
Collection item (an event)
---
layout: default
thumb: /images/event__screen-printing-basics.jpg
link: https://www.eventbrite.com/e/screen-printing-basics-tickets-41882948025
title: Screen Printing Basics
weekday: Wednesday
month: January
date-number: '10'
description: Join us for an after hours session to learn everything you need to know about screen printing in the Make Lab. We will be coating screens with emulsion, printing artwork onto transparencies, burning the image into the screen, washing out the stencil, mixing ink, prepping our work station, registering the paper, and finally pulling prints. The artwork always varies, so you’ll leave with a one-of-a-kind screen printed poster that you made yourself!
---
Interface
The best way to accomplish this is to use real dateTime and group_by_exp filter.
DateTime
---
layout: default
thumb: /images/event__screen-printing-basics.jpg
link: ...
title: Screen Printing Basics
description: ...
date: 2018-03-21 20:00
---
Note that for some reason date: 2018-03-21 doesn't work.
group_by_exp filter
Simplified print logic can be :
{% assign eventsByYear = site.events | group_by_exp:"event", "event.date | date: '%Y'" %}
{% for year in eventsByYear %}
<h1>{{ year.name }}</h1>
{% assign eventsByMonth = year.items | group_by_exp:"event", "event.date | date: '%B'" %}
{% for month in eventsByMonth %}
<h2>{{ month.name }}</h2>
<ul>
{% for event in month.items %}
<li>{{ event.title }}-{{ event.date | date: "%A, %B %d, %Y"}}</li>
{% endfor %}
</ul>
{% endfor %}
{% endfor %}
I have the following in my _config.yml file:
collections:
nr_qa:
output: true
permalink: /:collection/:name
title: 'Node-RED Questions and Answers'
descriptions: 'Node-RED is a flow-based (visual) programming tool. These pages have some information that may be currently missing from the documentaiton.'
github_pages:
title: 'GitHub Pages and Jekyll/Liquid'
description: 'Hints and tips on using Jekyll for publishing to GitHub Pages.'
output: true
permalink: /:collection/:name
and I want to create an automatic index for my collections. So I use code like this:
## {{ site.collections.github_pages.title }}
{{ site.collections.github_pages.description }}
<ul>
{% for item in site.github_pages %}
<li>
{{ item.title | replace:'_',' ' }}
<p>{% if item.description %}
{{ item.description }}
{% else %}
{{ item.excerpt | strip_html }}
{% endif %}</p>
</li>
{% endfor %}
</ul>
And yes, I know I've rather mixed up my markdown and html there. Not relevant to this question.
The problem is that {{ site.collections.github_pages.title }} and {{ site.collections.github_pages.description }} don't render anything even though I think they should.
Can anyone point out my mistake please?
The problem is that title and description should be included in each collection, and not in _config.yml.
Check out Accessing Collection AttributesPermalink for further details.
update
title can be present in each collection metadata in _config.yml. The problem is how you are accessing those variables.
One approach is to have a specific layout for each collection, then you can access them like:
{% assign col = site.collections | where: 'label','github_pages' | first%}.
TITLE: {{ col.title }}.
DESCRIPTION: {{ col.description }}.
I have a collections of projects. Part of each project is a list of people who have worked on that project:
---
layout: project
name: Important Project
participants:
- name: julia
role: owner
- name: paul
role: manager
- name: chris
role: implementer
---
Each of these people are in a collection themselves and have a page where their details are listed. I'd like to include the projects they've been working on and what their role was. This is my best effort but doesn't work:
{% for project in site.projects %}
{% if project.participants['name'] == {{ page.name }} %}
<p>{{ project.name }} - {{ project.participants['role'] }}</p>
{% endif %}
{% endfor %}
Any suggestions are most welcome.
Assuming this structure:
# _config.yml
collections:
- people
- projects
Then directory structure like:
_projects/project1.md
_people/person1.md
_people/person2.md
With person1.md front-matter like:
---
name: julia
---
And the above front-matter you provided, this is how to display the list of projects and roles of each person:
{% for person in site.people %}
Person {{person.name}}
{% for project in site.projects%}
{% assign person_project = project.participants | where:"name",person.name | first %}
Project: {{project.name}}
Role: {{person_project.role}}
{% endfor %}
{% endfor %}
Then the output looks like:
Person julia
Project: Important Project
Role: owner
Then you can improve the output as you wish, for example with a table:
{% for person in site.people %}
<table>
<caption>{{person.name}} projects</caption>
<tr>
<th>Project</th>
<th>Role</th>
</tr>
{% for project in site.projects%}
{% assign person_project = project.participants | where:"name",person.name | first %}
<tr>
<td>{{project.name}}</td>
<td>{{person_project.role}}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
output:
julia projects
Project Role
Important Project owner
I imagine that your participants items look like this :
---
short: julia
firstname: Julia
lastname: Last
layout: participant
---
Content
In your participant layout you can do :
<h2>Participant : {{ page.firstname }} {{ page.lastname }}</h2>
{{ content }}
<h2>Projects :</h2>
<ul>
{% for project in site.projects %}
{% for participant in project.participants %}
{% if participant.name == page.short %}
<li>{{ participant.role }} in {{ project.name }}</li>
{% endif %}
{% endfor %}
{% endfor %}
</ul>
In participant
I have a network of nodes, some of which are related to one another. I'm using Jekyll to power a website, and was hoping to use liquid tags to map those relationships.
So, the way I've been trying to do this is as follows.
A, which is in the category of 1, is related to B
B, which is in the category of 2, is related to A, and C
When I visit the page for A, I'd like to see B listed as being related.
I've defined the YAML front matter as such:
title: A
category: 1
tags:
- B.html
title: B
category: 2
tags:
- A.html
- C.html
My liquid template looks like:
<h2>{{ page.title }} <span class="label important">{{ page.category }}</span></h2>
<p>Last edited: {{ post.date | date_to_string }}</p>
<p><em>{{ content }}</em></p>
<h4>Related</h4>
<ul>
{% for post in site.tag.{{ post.url }} %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
To me, that looks like it should work. In reality, it doesn't.
Suggestions are welcome!
Also, relevant Github pages are here:
https://raw.github.com/salmonhabitat/salmonhabitat.github.com/master/_posts/2011-12-12-bycatch.md
https://raw.github.com/salmonhabitat/salmonhabitat.github.com/master/_posts/2011-12-12-accidental.md
https://github.com/salmonhabitat/salmonhabitat.github.com/blob/master/_layouts/post.html
What I was intending to happen was for 'Accidental injury' to show up under 'Marine bycatch's' Related nodes...
The first problem is that posts are basically "blind" to other posts in jekyll. It's impossible to the url (or title) of one post from inside another post in jekyll, with only the id of the former. Your site.tag.{{ post.url }}, while creative, would not work :) .
First, your front matter needs to be (unfortunately) a bit more complicated to be able to accomplish that:
title: A
category: 1
related_posts:
- title: B
href: /2010/01/01/B.html
- title: C
href: /2011/11/11/C.html
Notice that I've changed the name from "tags" to "related_posts". I feel it's more clear this way.
Now you can try this code:
<h2>{{ post.title }} <span class="label important">{{ post.category }}</span></h2>
<p>Last edited: {{ post.date | date_to_string }}</p>
<p><em>{{ content }}</em></p>
{% if post.related_posts %}
<h4>Related</h4>
<ul>
{% for related_post in post.related_posts %}
<li>{{ related_post.title }}</li>
{% endfor %}
</ul>
{% endif %}
While this is a bit more verbose than your version, it has an advantage - you can specify your own title in related posts, without being forced to use B or C.
Let me know if you have problems with this, and good luck!