Open andystevenson opened 2 years ago
Hhmm. I would have expected that to work, per https://www.11ty.dev/docs/layouts/#front-matter-data-in-layouts… but I've always found global _data/eleventyComputed.js files a bit unpredictable (see #2058, for example).
I guess the good news is that this seems consistent w/ 0.12.1 and 1.0.0. The bad news is, I don't see the expected results in either version:
KEY | VIA | EXPECTED | 0.12.1 | 1.0.0 |
---|---|---|---|---|
{{ whyNotMe }} |
local | "why not me" | "why not me" | "why not me" |
{{ allAboutTheBase }} |
layout | "all about the base" | "" | "" |
{{ title }} |
local | "index title" | "hello world" | "hello world" |
{{ layout }} |
eleventyComputed | "base.njk" | "base.njk" | "base.njk" |
Interestingly (or not, you decide), if I get rid of the _data/eleventyComputed.js file, I get the expected page title of "index title" (at least in 1.0.0, didn't check in 0.12.1 yet).
Similarly, if I change the eleventyComputed.js file to use functions, it sets the expected title (although I'm still not seeing a value for allAboutTheBase
from the layout file):
// _data/eleventyComputed.js
module.exports = {
layout(data) {
return data.layout || 'base.njk';
},
title(data) {
return data.title || 'hello world';
}
};
Which I guess makes sense. It seems like the _data/eleventyComputed.js was simply overriding the values in the original version and not using the template-specific values for title
. But when we switch to the function syntax, we can return an existing title [if it exists] and fall back to a default if it doesn't.
Thanks Peter that's helpful.
I tweaked _data/eleventyComputed.js as you suggested also adding in a function for allAboutTheBase.
module.exports = {
layout: (data) => data.layout || 'base.njk',
title: (data) => data.title || 'hello world',
allAboutTheBase: (data) => data.allAboutTheBase || 'what no base!',
}
It still didn't pickup the layout frontmatter from base.njk and rendered.
<p>why not me</p>
<p>what no base!</p>
<h1>index title</h1>
So it appears that for the Data Cascade if you have a global _data/eleventyComputed.js then it completely misses out 'Front Matter Data in Layouts' and will only catch 'Front Matter Data in a Template' if eleventyComputed.js writes the function as above (checking for data-in-a-template) to override the global eleventyComputed.js invocation?
Computed Data Front Matter Data in a Template Front Matter Data in Layouts (only in 0.x) Template Data Files Directory Data Files (and ascending Parent Directories) Front Matter Data in Layouts (moved in 1.0) Configuration API Global Data Global Data Files
Not sure if there is a simple fix... my only thought was that clearly _data/eleventyComputed.js is going to get invoked multiple times in the cascade. So maybe if the function signature changed to something like eleventyComputed(data, scope = 'global') then at least the function might intelligently work out what to do?
e.g.
...
eleventyComputed(data, 'global')
eleventyComputed(data, 'layout')
eleventyComputed(data, 'template')
eleventyComputed(data, 'computed')
I tweaked the simple repository with the above eleventyComputed.js https://github.com/andystevenson/11ty-eleventyComputed-issue
@andystevenson Yeah, I feel like there might be a bug here. Although it's more interesting the more I stare at it.
Even if I delete the _data/eleventyComputed.js file (and either move the layout
into the index.njk file, or create a super fun _data/layout.json file with the literal string "base.njk"
[because that's totally valid JSON and it works]… but it still doesn't find an allAboutTheBase
, even though it's defined in the layout file itself.
---
# /src/_includes/base.njk
title: 'all about the base (layout)'
allAboutTheBase: 'all about the base (layout)'
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
</head>
<body>
<p>DEBUG.allAboutTheBase={{ allAboutTheBase }}</p>
{{ content | safe}}
</body>
</html>
---
# /src/index.njk
title: 'index title (template)'
whyNotMe: 'why not me (template)'
---
<p>{{ whyNotMe }}</p>
<p>{{ allAboutTheBase }}</p>
<h1>{{ title }}</h1>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>index title (template)</title>
</head>
<body>
<p>DEBUG.allAboutTheBase=</p>
<p>why not me (template)</p>
<p></p>
<h1>index title (template)</h1>
</body>
</html>
I'm confused as to why <p>DEBUG.allAboutTheBase=</p>
is an empty string when it's defined directly in that layout file's front matter. Although I think it shows that it may not be related to _data/eleventyComputed.js? 🤷
@pdehaan thanks... one for @zachleat probably.
I implemented a _data/eleventyComputed that does the following.
base.njk has the following frontmatter
index.njk has the following content
This renders
Expected base.njk frontmatter to make it through the data cascade/merge Expected index.njk frontmatter title to make it through the data cascade/merge
Mac Book Pro macOS Monterey 12.2.1 @11ty/eleventy 1.0.0
Please see https://github.com/andystevenson/11ty-eleventyComputed-issue for a 'hello world' example