11ty Markdown -- group pets by color

Katie - Sep 8 '21 - - Dev Community

Back in November, I addressed a StackOverflow question about how dynamic "list" generation worked in 11ty compared to Drupal views. I explained the mental adjustments you'd have to go through when switching from a web site management system with a relational (SQL) data model vs. an object data model.

However, not really understanding Eleventy's handling of Markdown, I did so with all of the data inside a single .js file within the _data folder. It turns out Alec wanted to know more about crunching data from Markdown files in 11ty. Now that I understand 11ty's processing of .md files a bit better myself (and the ways you combine .md files with .11ty.js / 11ty.json files inside a folder to avoid repeating yourself within Markdown front matter), I decided to take another stab at making a web site that groups "kittens & puppies" by color -- this time with Markdown instead of JSON data. (Code; live site)

I'm pretty pleased with the results as an example of the way 11ty helps you store your data exactly how you want it, while also generating URLs according to your dreams.

Data

If you haven't seen the 5 kittens & puppies we're working with, you might want to take a moment to review our 2 cats & 3 dogs from my previous post.

Here's the TL;DR:

Kittens

  1. (kitten #1)
    • name: Oreo
    • colors:
      • black
      • white
    • slug: oreo
  2. (kitten #2)
    • name: Hershey
    • colors:
      • brown
    • slug: hershey

Puppies

  1. (puppy #1)
    • name: Fido
    • colors:
      • white
      • red
    • slug: fido
  2. (puppy #2)
    • name: Rover
    • colors:
      • tan
    • slug: rover
  3. (puppy #3)
    • name: Snickers
    • colors:
      • black
      • white
    • slug: snickers

If you'd like, see how I divided them up into actual Markdown files.

Keyword naming choices

If you're wondering my code uses a million different synonyms for the same concept like cat, kitten, meower, etc. -- see my article How to break (and rebuild) the Jamstack. When I'm trying to demonstrate how a complex piece of technology like 11ty works, I try to reduce the number of coincidental repetitions of a word. That way, if I reuse a word, you can see that it's because I had to refer to it by a name I previously gave it. In production, you'd probably just say cats over and over (indeed, I didn't bother to get as creative with synonyms for pets in places where I could've changed my naming standard), but I wanted to make sure I touched on the full power of "arbitrariliy renaming things" in Eleventy.

File structure

11ty would be more than happy to turn just about every file stored anywhere within /src/ (except /src/_includes) into a web page.

I've organized ".md files that are data" beneath /src/markdown/ and "non-.md files that use data" beneath /src/computed_pseudo_pages/.

Markdown

/src/markdown/pets/ has a file pets.11tydata.js (called pets after the name of its folder to invoke Eleventy magic-filenaming tricks) whose sole job is to ensure that cats Markdown files end up having kitties in the URL instead of cats, and that the dogs folder ends up as puppies in its URL, by setting a permalink for all pages rendered from files stored anywhere within /src/markdown/pets.

/src/markdown/pets/cats/ then has a file cats.11tydata.js that indicates every .md file in this folder should be treated as if it had 4 additional Front Matter fields:

  1. An 11ty layout template of layouts/default
  2. Two tags of kittehs & pets (pets being the most important tag, as it's going to make it easy for us to find all cats & dogs later)
  3. A type of, just for fun, PURR MACHINE
  4. A urlpart of kitties (as expected by pets.11tydata.js)

Then I did a similar exercise with /src/markdown/pets/dogs/dogs.11tydata.json.

/src/markdown/pets/cats/ has 2 .md files in it, each of which has a name front matter property and a colors front matter property:

  1. hershey.md
  2. oreo.md

/src/markdown/pets/dogs/ has 3 .md files in it, each of which also has a name front matter property and a colors front matter property:

  1. fido.md
  2. rover.md
  3. snickers.md

Obviously, at this point, there isn't a lot of reason to store cats & dogs separately, but at some point, they might branch apart -- for example, dogs might need a tricks property.

Pseudo-pages

Over in /src/computed_pseudo_pages/, there are 3 files:

  1. singleton_home.liquid, which creates our site's home page and demonstrates how to use an Eleventy include, which in turn demonstrates the 11ty magic of simply being able to loop over collections.pets, thanks to us having tagged all the dogs & cats with pets.
  2. loop_pet_gallery_paginated.liquid, which demonstrates making an archival "gallery" of all pets, displayed up to 3 at a time, using 11ty's pagination feature.
  3. loop_pets_by_color.11ty.js, which demonstrates grouping the pets by color and generating a URL full of brown pets, a URL full of black pets, a URL full of white pets, etc. I switched to JavaScript-based templating from Liquid-based templating because I needed to preprocess collections.pets into a different data structure before paginating it, and that was the best I could come up with.

Codebase and site

Be sure to check out the GitHub repository and its accompanying live web site.

I hope this has helped you see some of the crazy things you can do with Eleventy to store your data exactly how you want it while generating URLs exactly how you want them!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .