# Advice for filtering collection with routes

**URL:** <https://talk.jekyllrb.com/t/advice-for-filtering-collection-with-routes/5886>\
**Category:** Help\
**Created:** [April 15, 2021, 12:27pm UTC](https://talk.jekyllrb.com/t/advice-for-filtering-collection-with-routes/5886 "2021-04-15T12:27:22Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![grimes](https://avatars.discourse-cdn.com/v4/letter/g/958977/32.png) [@grimes](https://talk.jekyllrb.com/u/grimes)\
**Post date:** [April 15, 2021, 12:27pm UTC](https://talk.jekyllrb.com/t/advice-for-filtering-collection-with-routes/5886/1 "2021-04-15T12:27:22Z")

</div>

Hey there!

I’m not exactly new to Jekyll, but never had to work on this sort of desired structure. Apologies if I’m missing some obvious functionality.

If there is a way to achieve the following structure, how would you go about it in the cleanest, best practices kind of way.

Let’s say I have a large collection of places. Each of the place has two categories assigned, type and location.

For example:  
title: Cool Brewery  
type: Bar  
location: West

I’d like to filter using routes, so:  
/places/bars - page outputs all of the bars  
/places/bars/west - page outputs all of the bars within west

and so on  
/places/restaurants/east  
/places/bars/south

Any advice or example is much appreciated.  
Thanks!

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [April 15, 2021, 10:40pm UTC](https://talk.jekyllrb.com/t/advice-for-filtering-collection-with-routes/5886/2 "2021-04-15T22:40:57Z")

</div>

If you don’t need to actually have an page for each bar, then you could store all bar data in frontmatter of the bar/index.md, or a collection or of a YAML data file, then iterate over that. No need to iterate over paths because you could get only bars.

e.g. with frontmatter for bars/index.md

```auto
---
bar_info:
  - title: A
    description: ABC
  - title: B
    description: DEF
---

Add a for loop here over this array
{{ page.bar_info }}

```

But in case you want a page for each bar, then see my next answer.

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [April 15, 2021, 11:02pm UTC](https://talk.jekyllrb.com/t/advice-for-filtering-collection-with-routes/5886/3 "2021-04-15T23:02:54Z")

</div>

Let’s say you have directory setup like this

```auto
places/bars/
  index.md # menu listing of all bars
  abc.md
  def.md

```

Each page in Jekyll has the following attributes - you can use either for route.

```auto
{{ item.url }}
{{ item.dir }}

```

The **url** is browser path.

e.g. `/places/bars/` and `/places/bars/abc/`  
assuming you have pretty permalink.

Or `/places/bars/index.html` which is less useful for you and you’d have to replace the filename.

And **dir** is directory of the markdown file.

e.g. `places/bars/` - the same for both the index.md page and the other pages. This is a good one for you. More on that below.

* * *

Since the code will be for places/bars/index.md then using

```auto
{{ page.dir }}

```

Will evaluate to this (maybe a trailing slash?)

```auto
places/bars

```

So then that index.md must have

So then you could list all bars in the bar directory.

```auto
---
title: Bars
--- 

<ul>
{% for p in site.pages %}
  {% if p.dir == page.dir and p.name != 'index.md' %}
    <li>
      {{ p.title }} - {{ p.type }} - {{ p.location }}
    </li>
{% endif %}
{% endfor %}
</ul>

```

You could also add a link to click to the page with `a href="{{ p.url | relative_url }}:`

There I check equality that `{{ item.dir == page.dor }}` exactlyn- only at the exact same level and **not** in west directory. Which means you might get zero results if the bar pages are not in bars directly but in bars/west etc.

In that case you can do a contains match.

```auto
{% if p.dir contains page.dir and p.name != 'index.md' %}

```

Note the space before and after `contains.

You might also find a builtin Ruby method something like

```auto
{% if p.dir.startswith(page.dir) and p != page %}

```

Either approach will match both bars/abc.md _and_ bars/west/xyz.md

And then repeat that for loop on places/bars/west/index.md to match all the pages in the west directory only.

When you have that working, you can turn it into an includes snippet or layout so it is reusable on your bar pages and location listing.

Good luck.

---

<div class="post-metadata">

**Author:** ![BillRaymond](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/billraymond/32/5963_2.png) [@BillRaymond](https://talk.jekyllrb.com/u/BillRaymond)\
**Post date:** [April 15, 2021, 11:13pm UTC](https://talk.jekyllrb.com/t/advice-for-filtering-collection-with-routes/5886/4 "2021-04-15T23:13:14Z")

</div>

The two most popular ways to accomplish this are with Jekyll Collections or Jekyll Data. I will cover both in this response.

## The Jekyll Collections approach

Here, you create individual files for each of the breweries, and then you can show them one at a time (like a page or a post), or you can iterate through them to create a list.

In your \_config.yml file, add the line (anywhere):

```auto
collections:
  breweries:

```

Note: If Jekyll is running, even with livereload, you will need to stop and start again for the change to take effect.

Next, create a folder at the root level and name it `_breweries`. That folder corresponds to the collection you added to the `_config.yml` file.

Inside that folder, create as many breweries as you like. Every markdown file represents a brewery. You can add whatever YAML front matter you like.

**file** : `anchor-steam.md`

```auto
---
title: Anchor Steam Brewery
type: brewery
sub-type: na
location: San Francisco
---
## Famous brewery with a tasting room
Learn the traditions of this famous brewery...

```

**File** : `magnolia-brewery`

```auto
---
title: Magnolia Brewery
type: brewery
sub-type: restaurant
location: San Francisco
---
## Come for the beer stay for the fries
Tucked away in a corner in the historic Haight Ashbury district there lies a gem of a brewery and restaurant....

```

All the files you create can have whatever content you like, including pictures, links, videos, etc. It is like creating a single web page or podcast post for each one.

Now create a folder from the root and title it `breweries` (or whatever you want to call it).

Create two files in the `breweries` folder:

`all.html`  
`restaurants`

**File:** `all.html`

```auto
---
title: All Breweries
layout: default
---

{% for brewery in site.breweries %}
    <h1>Name: {{ brewery.title }}</h1>
{% endfor %}

```

**File:** restaurants.html

```auto
---
title: Restaurants
layout: default
---

{%- assign breweries = site.breweries| where: "sub-type", "restaurant" -%}
{% for brewery in breweries %}
    <h1>Name: {{ brewery.title }}</h1>
{% endfor %}

```

Now, you can go to your Jekyll site and go to `mysite/breweries/all` or `mysite/breweries/restaurants` and the breweries are filtered as you like.

Of course, I only display the title of the brewery, but you can display whatever metadata or content you want to display.

If you want to learn more about Collections, check out the official documentation:

> **[Collections](https://jekyllrb.com/docs/collections/)**
>
> Collections are a great way to group related content like members of a team or talks at a conference.

## The Jekyll Data approach

Here, you do not have to modify the \_config.yml file and you create a file containing a dataset of breweries. Jekyll can work with CSV, JSON, YML, and XML. I’m going to use YAML in this example.

Create a new folder at the root of your site and call it `_data` (this is a built-in folder name Jekyll uses so you can add data files).

In that new folder, create a file and call it `breweries.yml`.

Edit that file and add the following data:

```auto
items:
    - title: Anchor Steam Brewery
      type: brewery
      sub-type: na
      location: San Francisco
      Description: "Learn the traditions of this famous brewery..."
    - title: Magnolia Brewery
      type: restaurant
      sub-type: restaurant
      location: San Francisco
      description: "Tucked away in a corner in the historic Haight Ashbury district there lies a gem of a brewery and restaurant...."

```

Now, in the root of your site, create a new folder and call it `brewery-data` (or whatever name you want).

In the `brewery-data` folder, create two files:

`all.html`  
`restaurants.html`

**File:** `all.html`

```auto
---
title: All Breweries (from data)
layout: default
---

{% for brewery in site.data.breweries.items %}
    <h1>Name: {{ brewery.title }}</h1>
{% endfor %}

```

**File:** restaurants.html

```auto
---
title: Restaurants (from data)
layout: default
---

{%- assign breweries = site.data.breweries.items| where: "sub-type", "restaurant" -%}
{% for brewery in breweries %}
    <h1>Name: {{ brewery.title }}</h1>
{% endfor %}

```

To test this, you can go open your Jekyll site in the browser and go to `mysite/brewery-data/all` or `mysite/brewery-data/restaurants`.

Once again, my example just displays the name of the brewery, but you can add any other data elements you want.

## Conclusion

Both methods work great, but it will depend on how you want to manage things. If each place has its own unique approach to how you want to describe it, then the _collections_ approach is probably better.

The _data_ approach is really easy and accessible, but you have to know how to work with data. Also, what happens when you want to add images and manage the content for the site? Working with data becomes unwieldy once you think of every data element you want to put in there. You may also find it is harder to do grammar and spell-checking when using data.

If you want to go the data route, I suggest you watch the following video and the following additional videos that explain Jekyll data and teaches you how to use it:

[![](https://canada1.discourse-cdn.com/flex030/uploads/jekyllrb/original/2X/e/ebcebdc7ddbf27f2c81dab4c3acc4c0cb6131624.jpeg "Working with Jekyll Data: Part 1 (slides only)") ](https://www.youtube.com/watch?v=7Jj-KX40iTE)

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [April 17, 2021, 6:36am UTC](https://talk.jekyllrb.com/t/advice-for-filtering-collection-with-routes/5886/5 "2021-04-17T06:36:48Z")

</div>

Yes collections and data both work for storing and displaying data.

For collections, if you set up the config with `output: true` then each time in the collection will get its own page. The data approach doesn’t do this, unless you use a generator plugin which is not worth it here.

For collections, having subtype is an interesting approach because then all bars can be in the same directory and they are easy to iterate over. You even prefix names as west-abc.md and east-def.md to sort them easily for editing and you could extract the location from item.name even.

A downside of the collection approach compared to my routing answer is that collections let you group by folder. If you make a collection called bars, then items in bars/west and bars/east are all seen as in a single bars collection.  
However, you _could_ make a collection for east, west, etc. The hassle is remembering to add the name to config file when creating it (if you have more than 4 locations and these grow). Plus you lose the nesting approach. In order to get all bars, you have to iterate over west collection and then east collection etc.

So if you if you do go for my suggested routing approach, you could use pages or collections even. I don’t see an advantage with using collections as pages and collection items can both store frontmatter.

Maybe collections would be useful if you want to treat bars as a collection and using url routing within that and then restaurants as another collection. But it would need more specific code for each collection, while my code **generalizes** well to use the same layout for any page at any level (even if you go 4 levels deep as places, bars, west, irish). without having to hardcode using site.bars in the for loop.

To demonstrate, I have easy path-based routing _without_ collections and using multiple levels of nesting down. If I add another `new-dir/index.md` page at any level, it automatically becomes part of the visible menu. No need to add a new collection in the config.

> **[Vue](https://michaelcurrin.github.io/dev-cheatsheets/cheatsheets/javascript/packages/vue/)**
>
> A collection of code snippets and CLI guides for quick and easy reference while coding

* * *

Another thing to note on collections is that the bars listing page should **not** exist in the bars collection. Your structure would be

```auto
_bars/
    abc.md
    def.md
bars.md # permalink: /bars/

```

And the weakness here is that you need to tell the bars.html page that it belongs to the bars collection structure. While my approach puts bars.md as index.md inside bars directory.

---

<div class="post-metadata">

**Author:** ![BillRaymond](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/billraymond/32/5963_2.png) [@BillRaymond](https://talk.jekyllrb.com/u/BillRaymond)\
**Post date:** [April 17, 2021, 8:42am UTC](https://talk.jekyllrb.com/t/advice-for-filtering-collection-with-routes/5886/6 "2021-04-17T08:42:54Z")

</div>

All I’m saying is we have some great breweries and brewery bars here in San Francisco 🙂

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [April 17, 2021, 8:31pm UTC](https://talk.jekyllrb.com/t/advice-for-filtering-collection-with-routes/5886/7 "2021-04-17T20:31:04Z")

</div>

We have cool names here in Cape Town.

Darling Brewery. Hoghouse Brewing Company. Jack Black Brewing Company. Devils Peak Brewery. Woodstock Brewery, Hey Joe Brewery.

---

<div class="post-metadata">

**Author:** ![BillRaymond](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/billraymond/32/5963_2.png) [@BillRaymond](https://talk.jekyllrb.com/u/BillRaymond)\
**Post date:** [April 17, 2021, 10:37pm UTC](https://talk.jekyllrb.com/t/advice-for-filtering-collection-with-routes/5886/8 "2021-04-17T22:37:37Z")

</div>

Much more interesting!

---

<div class="post-metadata">

**Author:** ![RickGrimes](https://avatars.discourse-cdn.com/v4/letter/r/e480ec/32.png) [@RickGrimes](https://talk.jekyllrb.com/u/RickGrimes)\
**Post date:** [April 19, 2021, 3:54pm UTC](https://talk.jekyllrb.com/t/advice-for-filtering-collection-with-routes/5886/9 "2021-04-19T15:54:30Z")

</div>

I really appreciate such detailed responses.

What @MichaelCurrin suggested is something I thought about. Going the manual way and not using collections at all, just nesting pages. Just like on your Dev Cheatsheets project.

But I can’t help myself, it doesn’t seem like the right way, does it? 🙂  
I’m trying to think of potential downsides, for ex. working with some kind of CMS, all those pages would not render too nicely in those, most likely…

Anyhow, appreciate the input once again!
