Deniz Akşimşek |

Eleventy + Markdown + CoffeeScript = ❤

also on DEV

I’ve started using CoffeeScript instead of YAML for frontmatter, and it works like a dream. Endorsed by Zach Leatherman.

Markdown with Frontmatter

As far as I know, Jekyll is the origin of using a YAML block at the top of a Markdown file for metadata. It’s not hard to imagine why this became popular — associating prose with data is a common use case, and though they have their issues, both Markdown and YAML look pretty[1].

Eleventy Frontmatter

Eleventy uses frontmatter blocks (delimited by ---) for all kinds of files. Markdown posts, HTML partials and Nunjucks/EJS/Liquid/… templates can all have them. The data in the frontmatter can then be used in templates. In the following, title is not a reserved name:

title: 'A Blog Post'

# {title}

Lorem ipsum dolor sit amet...

We could have used name, heading or kdsad983erj33.

Eleventy’s “Computed Data” feature relies on functions in the frontmatter. As YAML doesn’t have functions, you are expected to use JS (well, you can use template strings I guess…):

title: "My page title",
eleventyComputed: {
currentDate: () => new Date().toLocaleString()
<!doctype html>
<!-- … -->
<p>This website was last generated on {{ currentDate }}</p>
<!-- … -->

Computed data is cool. Among other things, it allows me to move logic away from my templates and express it in an actual programming language. However JS frontmatter is not very pretty, and I don’t want to convert my whole frontmatter just for one function.

If only there was a language that had the expressive power of JS, and the visually clean data notation of YAML…

CoffeeScript All The Time!

CoffeeScript is actually mentioned in the GitHub repo for gray-matter, the library Eleventy uses to parse frontmatter. Compared to YAML, it’s not much more verbose:

title: Street sign in İstanbul
date: 2020-10-10T19:27:39+03:00
- place
- design
uPhoto: /assets/photos/IMG20201007085906-02.jpeg
türkçe: /2020/istanbul-sokak-tabelasi/

<!-- YAML -->
title: 'Street sign in İstanbul'
date: '2020-10-10T19:27:39+03:00'
tags: ['place', 'design']
uPhoto: '/assets/photos/IMG20201007085906-02.jpeg'
türkçe: '/2020/istanbul-sokak-tabelasi/'

<!-- CoffeeScript -->

The CoffeeScript code above is actually fully YAML-compatible! This keeps my templates portable. And with computed data:

layout: 'layout'
syndicationLinks: (data) ->
DEV: data.devToSyndication[]

<article class="h-entry">
<!-- ... -->
{%for silo, link in syndicationLinks%}
<a class="u-syndication" href="{{link}}">{{silo}}</a>
{%if not loop.last%} | {%endif%}

I think that computed frontmatter gives a nice balance of logic-less[2] and logic-full templates.

  1. “It looks pretty” is often what people really mean when they call something “human-readable”. ↩︎

  2. Logicless templates: For people who will never need to make an HTML monthly calendar! ↩︎