Recently, I was setting up a landing page for a project in Bridgetown (highly recommended!). Later on, I began adding a blog section, and since I envisioned myself creating more content, played around with NetlifyCMS as a lightweight CMS alternative.
I followed @andrewmcodes excellent tutorial here:
Creating a blog with Bridgetown and Netlify CMS
Andrew Mason ・ Jul 11 '20
The rest of this post builds up on his groundwork, so if you haven't, go read it first!
Customize Frontmatter Metadata
Every blog has its own set of metadata for its posts, but most often they include a subset of
- title
- description
- categories
- tags
- featured image
- post author
- publish date
A quick review of the NetlifyCMS docs revealed that they are managed by a YAML key called fields
that is part of a collection
definition.
Every field at the least needs to possess
- a
label
(that's how NetlifyCMS will label the field) - a
name
(that's how your metadata will end up in your frontmatter), and - a
widget
(which translates roughly to the data type and determines how your field is displayed by NetlifyCMS) - and, depending on the chosen
widget
, a set of other sub-keys (consult the NetlifyCMS docs for more precise instructions)
So here's how that might look in your NetlifyCMS config.yml
file:
# ...
collections:
- name: blog
# ...
fields:
- { label: Layout, name: layout, widget: hidden, default: post }
- { label: Title, name: title, widget: string }
- { label: Description, name: description, widget: text }
- { label: Featured Image, name: image, widget: image }
- { label: Categories, name: categories, widget: list }
- label: Author
name: author
widget: object
fields:
- {label: Name, name: name, widget: string}
- {label: Email, name: email, widget: string}
- { label: Publish Date, name: date, widget: datetime }
- { label: Body, name: body, widget: markdown }
Observe that the author
field uses a widget of type object
, which necessitates to define which fields
that object (the YAML key/value pairs that make up this field) includes. After committing these configuration changes, your post editor might look like this:
Referencing Authors
We can do better though, than to manually add an author's name and email every time. Imagine your blog has a couple dozen authors, you're quickly going to mistype something and sabotage any backlinks to the author. Luckily, NetlifyCMS knows a relation widget, allowing to reference a different collection.
So, let's set up an authors
collection. In Bridgetown, everything you need to do is add it to your config:
collections:
- authors
If you want, you can even have it output author pages automatically. Now we have to reference this collection in our NetlifyCMS config.yml
, too:
collections:
- name: authors
label: Authors
folder: src/_authors/
extension: .md
format: frontmatter
create: true
fields:
- {label: Name, name: name, widget: string}
- {label: Email, name: email, widget: string}
# ...
- name: blog
# ...
fields:
# ...
- label: Author
name: author
widget: relation
collection: authors
valueField: email
displayFields: ["name"]
searchFields: ["name", "email"]
The alert reader will have noticed that our collection definition resembles exactly our object
definition from above. In our blog
collection (shown below) we now reference the author as a relation
widget, which requires a few more keys:
- the
collection
- a
valueField
(which will be stored as the frontmatter value) - a
displayFields
array (the fields displayed in the UI widget), and - a
searchFields
array to allow for interactive lookup of authors.
Now for starters, let's add an author in src/_authors/julian-rubisch.md
:
---
name: Julian Rubisch
email: ...
---
After a refresh, our widget now looks like this:
If you save this post in NetlifyCMS, you will find your frontmatter filled out comfortably for you:
title: ...
description: ...
image: /images/uploads/....jpeg
categories:
- Blog
author: .....
date: 2020-08-30T08:08:46.681Z
Render it in Bridgetown
The only remaining task is to actually render these metadata in your liquid tags, and for the new authors
collection, we need a little tweak. To find the corresponding post author object out of your collection, you need to do something like
{% assign author = site.authors | where: "email", post.author | first %}
...
{{ author.name }} {{ author.email }}
in your post layout.
Bonus: A Custom Liquid Filter
To my eye, this reads clunky enough to warrant its own Liquid filter. Praise the Ruby gods, Bridgetown comes with a handy DSL to accomplish this. In plugins/builders/filter.rb
, key this in:
class Filters < SiteBuilder
def build
liquid_filter "find_author_by_email", :find_author_by_email
end
def find_author_by_email(email)
site.collections["authors"]
.select { |author| author.email == email }
.first
end
end
This will allow your liquid to boil down to:
{% assign author = post.author | find_author_by_email %}
...
{{ author.name }} {{ author.email }}
Notabene: a forthcoming feature in Bridgetown will make this even easier:
Top comments (1)
Excellent explanation! Thanks!