Generate a list of a YAML front matter variable and remove duplicates


#1

Hoping someone can help me out. I’m trying to generate a list of a front matter variable called “label” that I have on my posts. I currently have code working where it lists the variable, however if I have the same label on multiple posts, its will list each instance rather than only returning the unique values…I have tried using | uniq with no luck. What should I be doing to get a list of only the unique front matter variables?

Here’s my liquid code I currently have:

{% assign blogposts = site.categories.blog | sort: ‘label’ %}
{% for post in blogposts %}
{{ post.label }}
{% endfor %}


#2

You just want the list of labels not a list of articles with the particular labels?

Maybe this will help:

https://www.jokecamp.com/blog/listing-jekyll-posts-by-tag/


#3

When I tried using tags, functionality wasn’t working as expected so I created a custom YAML variable to handle it.

Perhaps my approach is completely wrong.


#4

whoops - you know I poked around for an answer for you for quite a while, and was originally on track that it was a custom variable (not tags) but then saw that link and it was much simpler than the other solutions and I forgot that it was a custom variable. No wonder it was so simple.

Liquid has lots of Array based filters and functions, I think you can do what you want with a bit of work.

This SO post seems sort of promising, though again it is using tags but maybe if you swap out tag for label it will work (in the second answer, first answer may work as well but is more complex)?


#5

So I changed my approach to using categories…which eliminates the duplicates I want…however its showing categories in the list I do not want to see…If loops or unless loops do not work to hide specific categories…now what do I do?

{% for category in site.categories %}

{% endfor %}

I have two categories (work and blog) that I do not want to appear on the page I am trying to implement this list on.


#6

I don’t understand - you have 2 categories? or several categories of which those 2 you don’t want to show? More info on what you want would be helpful.

What have you tried with if / unless? seems like they should work for that.


#7

So the way the site is structured…I currently have 4 automatic categories because I have 4 folders with a _posts folder benetah them…

Of those 4, I want to hide two of them so that I only see the 2 that relate to categories within the blog portion.

Here’s the updated code using categories and an unless, which returns blank when i preview it:

{% for category in site.categories %}

{% unless site.category == “work” %}

{% endunless %}

{% endfor %}

I’ve also tried using site.categories.blog and that also fails…

I just want to say I appreciate you helping me on this…doesn’t seem like it should be as hard as it has been so far.


#8

you may need to try site.category[0] == "work" or maybe it is [1] not [0]. I don’t quite remember. I think you are getting an array of categories and you probably need to match the correct part of it?

It does seem like things should be simpler sometimes, but there are so many use cases and it can pretty much all be done, you just have to be able to work with arrays and what not.

At one point I found it helpful to output the value of the whole array and that made it easier for me to understand what is really going on. Try putting just {{site.categories}} somewhere and see what you get.


#9

I don’t think site.category is a thing… if you do {{ site.category | inspect }} it’ll help you debug to see it’s value. When I tested it, it’s nil which would explain why you’re not getting anything.

Instead of site.category in your unless statements why not use category?
If the for loop is working as intended it should be assigning category with the value of the current category it’s encountering as it loops through the site.categories array.

In theory it would eventually be equal to work, so when it encounters your unless statement it would then spit out the relevant data for {{ category | first | replace: '-', '' | capitalize }}.

{% for category in site.categories %}
  {% unless category == "work" %}
    {{ category | first | replace: '-', '' | capitalize }}
  {% endunless %}
{% endfor %}

You may also be able to use Jekyll’s where filter in combination with assign to get a more fine tuned object to pull post data from.


#10

do that ^^. See, sometimes it really is simple, not sure why that escaped me, other than MM actually knows what he is doing and I just try things until they work.


#11

using category instead of site.category leaves me with same result…a list of all categories and no filtering.

Is there a way I can change the folder structure to where the work section doesn’t get treated like an automatic category? Could i make that folder a collection instead? Would that help? I assume I would be able to loop the pages in the collection just like looping posts?


#12

ok well maybe we were both half right - this works for me:

{% for category in site.categories %}
  {% unless category[0] == "Gimp" or category[0] == "Photoshop" %}{{ category | first | replace: '-', '' | capitalize }}
  {% endunless %}
{% endfor %}

if you change it to the 2 cats you want to exclude it should work.

Also, if you output {{ site.categories }} somewhere on its own - outside of a loop, you should see what that object contains - sort of key value pairs where item [0] is the cat name, and item [1] is all the associated data, which probably just shows up as a #. but it contains all the front matter and the content.


#13

SUCCESS!

That worked like a charm…what is the [0] saying in the liquid code?

Thank you so much again for the assistance.


#14

[0] refers to the position in the array. Liquid arrays start at 0.