Eleventy: Is it possible to use data in front matter?

Created on 10 Sep 2018  路  9Comments  路  Source: 11ty/eleventy

Is it possible make use of data in front matter? or use existing front matter in other front matter?

My template order is roughly post > post template > base template. I'd like to be able to set things in frontmatter that 'trickle up' - and can be used by other frontmatter. Or use a data variable inside of front-matter.


What I'd like:

Base template:

<body class="{{bodyClasses}}">

Post template:

---
layout: layouts/base-template.njk
bodyClasses: post post__{{page.fileSlug}} {{pageClasses}}
---

Individual post:

---
layout: layouts/post-template.njk
pageClasses: foobar
permalink: /amazing-url
---

At the moment it looks like {{pageClasses}} gets printed as a string rather than interpreted.

So I get this:
<body class="post post__{{page.fileSlug}} {{pageClasses}}">

Rather than:
<body class="post post__amazing-url foobar">

Context: I'm new to front matter, so perhaps this just isn't something it's designed for. Any suggestions you have would be welcome. I note that permalinks seem to be able to use variables, so I assume it's not completely impossible for frontmatter to contain them.

education enhancement

Most helpful comment

New in v0.11.0 it's now possible to use the eleventyComputed feature like so :

---
eleventyComputed:
  bodyClasses: "post post__{{page.fileSlug}} {{pageClasses}}"
---

All 9 comments

We did play around with a feature to do this for awhile (and it鈥檚 undocumented) but I wasn鈥檛 real happy where it landed and now I think it鈥檚 mostly eclipsed by JavaScript data files. You can do any manner of variable reuse in there.

You can use JS Data Files alongside front matter, if you鈥檇 like, although you wouldn鈥檛 be able to use your front matter to set values in your JS Data Files.

https://www.11ty.io/docs/data-js/

Thanks for the fast reply. I don't think data files fully achieve what I want - which is to be able to make use of front matter from posts in intermediary templates to set values on my base template. That or I'm not getting it.

I've just tried with a pages.json in my posts directory with the following:

{
    "bodyClasses": "post post__{{page.fileSlug}} + {{pageClasses}}",
     "permalink" : "/{{page.fileSlug}}/index.html"
}

Both page.fileslug and pageClasses get printed as strings. I've also tried using {% set pageClasses = 'foobar' %} within my post, but that doesn't work either.

Oh, hmm. Yeah I see the value there. Just for the record, you can achieve something similar without leaning so heavily on front matter.

Base template

<body class="{% if pageType %}{{ pageType }} {{ pageType }}__{{ page.fileSlug }}{% endif %} {{ pageClasses }}">

Post template

Set pageType here:

layout: layouts/base-template.njk
pageType: post
---

Individual post

layout: layouts/post-template.njk
pageClasses: foobar
permalink: /amazing-url
---

Does that do what you need?

It does for this use case (I went for something similar to this already), but I was aiming for less template specific stuff in my base template.

My class structure may change per category, so having {{pageType}}__{{page.fileSlug}} isn't necessarily universal. Right now it just means I'll have several variables in that base template. Not an a big issue though - just a neatness thing.

FWIW I feel there would be value in being able to concatenate / otherwise use existing data in frontmatter. I can see people using /posts.json to apply common attributes, and then in an individual post want to apply supplemental ones. It's great there's a clear order of priority. Letting frontmatter access the context would let something higher up the chain decide to append rather than reuse if it wanted.

Watch for the renderData feature to be documented that will solve this exact problem. It鈥檚 been shipping for awhile but is undocumented at the moment. Follow along at #238!

Hey @zachleat! I'm hesitant with renderData- my reading of it feels like it's rather complex.

Being able to directly use variables would be much nicer. It sounds like that's too hard though. Better to have a way of doing it though.

Related: upvotes needed at https://github.com/11ty/eleventy/issues/335

You can use JS Data Files alongside front matter, if you鈥檇 like, although you wouldn鈥檛 be able to use your front matter to set values in your JS Data Files.

Hey @zachleat, are we still unable to access front matter data in JS data files? Is there any chance this will be added in the future?

New in v0.11.0 it's now possible to use the eleventyComputed feature like so :

---
eleventyComputed:
  bodyClasses: "post post__{{page.fileSlug}} {{pageClasses}}"
---
Was this page helpful?
0 / 5 - 0 ratings

Related issues

ndaidong picture ndaidong  路  4Comments

AjitZero picture AjitZero  路  3Comments

zellwk picture zellwk  路  3Comments

DirtyF picture DirtyF  路  3Comments

zac-heisey picture zac-heisey  路  3Comments