Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Jekyll to sort posts by a custom YAML front matter variable?

I'm trying to create a page in my Jekyll site that will display a custom variable and list the posts that contain that custom variable.

I have created a movie review blog using a template Thiago Rossener created: Thiago's Template: https://github.com/thiagorossener/jekflix-template My Site: https://www.howdareyoureview.com/

in each post, I have defined custom variables in the YAML front matter that relate to the movie's details (i.e actor, director score, etc.)

for example:

---
layout: post
title: "Baby Driver"
image: 'https://res.cloudinary.com/how-dare-you-review/image/upload/c_fill,h_399,w_760/v1529865791/baby-driver.png'
tags:
- action
score: 72
director: Edgar Wright
written-by: Edgar Wright
staring: 
- Ansel Elgort
- Lily James
- Eiza González
- Jon Hamm
- Jamie Foxx
---

I want to create pages exactly like the tags page that already exists in this template: https://www.howdareyoureview.com/tags/

except I would want to sort by director, starring, etc. instead of by tags. the tags page is created using the following code in a tags.html file:

---
layout: minimal
title: "#Tags"
permalink: /tags/index.html
description: "Procure por sua #tag favorita."
---

<div class="tags">
{% assign tags_list = site.tags %}
  {% if tags_list.first[0] == null %}
    {% for tag in tags_list %}
        <a href="#{{ tag | slugify }}">{{ tag }}</a>
    {% endfor %}
  {% else %}
    {% for tag in tags_list %}
        <a href="#{{ tag[0] | slugify }}">{{ tag[0] }}</a>
    {% endfor %}
  {% endif %}
{% assign tags_list = nil %}
</div>

{% for tag in site.tags  %}
    <div class="tag-wrapper">
    <span class="tag-title" id="{{ tag[0] | slugify }}">{{ tag[0] }}</span>
    <ul class="post-list">
        {% assign pages_list = tag[1] %}
        {% for post in pages_list reversed %}
            {% if post.title != null %}
            {% if group == null or group == post.group %}
            <li><a href="{{ site.url }}{{ post.url }}">{{ post.title }}<span class="entry-date"><time datetime="{{ post.date | date_to_xmlschema }}" itemprop="datePublished">{{ post.date | date: "%m/%d/%Y" }}</time></a></li>
            {% endif %}
            {% endif %}
        {% endfor %}
        {% assign pages_list = nil %}
        {% assign group = nil %}
    </ul>
</span>
</div>
{% endfor %}

To achieve this for the custom variables I created I tried replacing "tag/tags" with director and saving the file out into to root directory as "directors.html" but the page is blank.

---
layout: minimal
title: "#Directors"
permalink: /directors/index.html
description: "Procure por sua director favorita."
---
<div class="directors">
{% assign directors_list = site.director %}
  {% if directors_list.first[0] == null %}
    {% for director in directors_list %}
        <a href="#{{ tag | slugify }}">{{ director }}</a>
    {% endfor %}
  {% else %}
    {% for director in directors_list %}
        <a href="#{{ director[0] | slugify }}">{{ director[0] }}</a>
    {% endfor %}
  {% endif %}
{% assign directors_list = nil %}
</div>

{% for director in site.director  %}
    <div class="director-wrapper">
    <span class="director-title" id="{{ tag[0] | slugify }}">{{ director[0] }}</span>
    <ul class="post-list">
        {% assign pages_list = director[1] %}
        {% for post in pages_list reversed %}
            {% if post.title != null %}
            {% if group == null or group == post.group %}
            <li><a href="{{ site.url }}{{ post.url }}">{{ post.title }}<span class="entry-date"><time datetime="{{ post.date | date_to_xmlschema }}" itemprop="datePublished">{{ post.date | date: "%m/%d/%Y" }}</time></a></li>
            {% endif %}
            {% endif %}
        {% endfor %}
        {% assign pages_list = nil %}
        {% assign group = nil %}
    </ul>
</span>
</div>
{% endfor %}

Since the code and the concept is exactly the same as the way tags are populated - I cannot understand why this doesn't work - I'm hoping someone can assist!

Here is my entire directory for reference: https://github.com/howdareyoureview/howdareyoureview.github.io

like image 381
zachsaul Avatar asked Oct 29 '22 09:10

zachsaul


1 Answers

Tags page uses site.tags, which is an array of site.posts grouped by tag, created by Jekyll at generation time.

You're trying to replicate by targeting site.directors but this expected array doesn't exist. But, you can use the group_by filter to achieve your goal.

<div class="directors">
  {% assign directors = site.posts | group_by: 'director' | sort: "name" %}
  {% for director in directors %}
    {% if director.name == "" %}
      {% assign name = "Anonymous" %}
    {% else %}
      {% assign name = director.name %}
    {% endif %}
    <a href="#{{ name | slugify }}">{{ name }}</a>
  {% endfor %}
</div>

{% for director in directors %}
<div class="director-wrapper">
  {% if director.name == "" %}
    {% assign name = "Anonymous" %}
  {% else %}
    {% assign name = director.name %}
  {% endif %}
  <span class="director-title" id="{{ name | slugify }}">{{ name | debug }}</span>
    <ul class="post-list">
      {% assign pages_list = director.items %}
      {% for post in pages_list reversed %}
        <li><a href="{{ site.url }}{{ post.url }}">{{ post.title }}<span class="entry-date"><time datetime="{{ post.date | date_to_xmlschema }}" itemprop="datePublished">{{ post.date | date: "%m/%d/%Y" }}</time></a></li>
      {% endfor %}
    </ul>
  </span>
</div>
{% endfor %}

Tip : You can use the inspect filter to debug your vars. {{ myvar | inspect }}

like image 163
David Jacquel Avatar answered Nov 12 '22 14:11

David Jacquel