19
votes

I'm rebuilding my company's current site in Jekyll and attempting to set up the structure around a content model using objects (files in a collection) that have attributes (key/value pairs in YAML front-matter). Simple conceptual stuff designed to demonstrate effective content modeling to my team.

Anything on the site that gets reused becomes an object, with the type of object defined by the specific collection that contains its file. So, I have a "services" collection for services offered by the company, a "clients" collection, and a "people" collection with a file for each person.

The problem I'm having is referencing a specific item in a collection. For example, I want my posts to have authors. I've found a ton of solutions for this using _data, but I want my authors to have pages and collections automatically outputs a page for each person. I've been able to get _data to generate pages, but I have no control over the order in which items are listed, whereas with a collection there are a lot of ways for me to control the order.

My current solution feels hacky. I'm giving each person an id which is equal to "firstname-lastname" so in the YAML front-matter it would say id: steve-hickey. Then I use the following code to loop through every person on the site and return any that match the author-id specified in the post.

The post layout template:

---
layout: default
---

<header class="intro post-header">
  <h1>{{ page.title }}</h1>
  {% assign people = site.people | where:"id", page.author-id %}
  {% for person in people %}
  <p>Written by <a href="/about/{{ page.author-id }}/">{{ person.first-name }} {{ person.last-name }}</a> on <p>{{ page.date | date: '%B %d, %Y' }}</p></p>
  {% endfor %}
</header>
<div class="post-body">

{{ content }}

</div>

A post's front-matter:

---
title: User Offboarding
layout: post
nav-area: blog
author-id: steve-hickey
---

A person file from the people collection:

---
id: steve-hickey
first-name: Steve
last-name: Hickey
job: User Experience Strategist & AUX Director
layout: person
nav-area: about
portrait-url:
---

It seems like there should be a way to identify a specific file or object based on a unique attribute that it already possesses, such as its name or url. That way I can just point to a specific object instead of evaluating all of them for a unique property I have to write. But after 3 days of searching I can't find a good answer to this.

1

1 Answers

28
votes

If people are unique in your collection {% assign author = site.people | where:"id", page.author-id %} will return an array with one element. In order to directly access this element do :

{% assign author = site.people | where:"id", page.author-id  | first %}

This grab the first (and only) element in you array. You now do {{ author.anykey }} directly.