eleventy
eleventy copied to clipboard
Check if a global data with `page.fileSlug` files exists
I need to know how can I check in a njk file if another file with a variable name exists. I have the following content source tree:
content/
- items/
- - first.njk
- - second.njk
- - third.njk
etc...
all with "layout": "layouts/item.njk", and
data/
- items/
- - first.json
- - second.json
etc...
For I want is that item.njk layout check if there is a file under data/items with the same name as its owner, under content/items. If so, is shows us the content of it, else tell us that we need to create a file with some content under data/items/{{ fileSlug }}.json
Is it possible?
I'm in a similar situation. Do you remember if you figured this out?
@thedamon You might be able to do this with a custom shortcode or filter.
Where the filter checks uses the sync node:fs module to check if the file exists and throw a hard error if the required global data file is missing.
eleventy.config.js
const fs = require("node:fs");
const path = require("node:path");
/**
* @param {import("@11ty/eleventy/src/UserConfig")} eleventyConfig
* @returns {ReturnType<import("@11ty/eleventy/src/defaultConfig")>}
*/
module.exports = function (eleventyConfig) {
eleventyConfig.addShortcode("data_file_exists", function (slug) {
if (!slug) {
slug = this.page.fileSlug;
}
const dataFile = path.join("src/_data/items", `${slug}.json`);
if (!slug || !fs.existsSync(dataFile)) {
throw new Error(`Missing data file: "${dataFile}"`);
}
return "";
});
return {
dir: {
input: "src",
output: "www",
}
};
};
src/content/items/third.njk
The "third" fileSlug is optional; the shortcode should default to this.page.fileSlug.
---
---
{%- data_file_exists "third" -%}
<h1>{{ items.third.title }}</h1>
DIRS
tree -A --gitignore
tree -A --gitignore
.
├── eleventy.config.js
├── package-lock.json
├── package.json
└── src/
├── _data/
│ └── items/
│ ├── first.json
│ └── second.json
└── content/
└── items/
├── first.njk
├── second.njk
└── third.njk
5 directories, 8 files
OUTPUT
Missing data file: "src/_data/items/third.json" (via Template render error)
> eleventy
[11ty] Problem writing Eleventy templates: (more in DEBUG output)
[11ty] 1. Having trouble rendering njk template ./src/content/items/third.njk (via TemplateContentRenderError)
[11ty] 2. (./src/content/items/third.njk)
[11ty] EleventyShortcodeError: Error with Nunjucks shortcode `data_file_exists` (via Template render error)
[11ty] 3. Missing data file: "src/_data/items/third.json" (via Template render error)
[11ty]
[11ty] Original error stack trace: Error: Missing data file: "src/_data/items/third.json"
[11ty] at Object.<anonymous> (/private/tmp/11ty-873/eleventy.config.js:15:13)
[11ty] at Object.<anonymous> (/private/tmp/11ty-873/node_modules/@11ty/eleventy/src/BenchmarkGroup.js:32:26)
[11ty] at ShortcodeFunction.run (/private/tmp/11ty-873/node_modules/@11ty/eleventy/src/Engines/Nunjucks.js:216:35)
[11ty] at Template.root [as rootRenderFunc] (eval at _compile (/private/tmp/11ty-873/node_modules/nunjucks/src/environment.js:527:18), <anonymous>:9:76)
[11ty] at Template.render (/private/tmp/11ty-873/node_modules/nunjucks/src/environment.js:454:10)
[11ty] at /private/tmp/11ty-873/node_modules/@11ty/eleventy/src/Engines/Nunjucks.js:411:14
[11ty] at new Promise (<anonymous>)
[11ty] at /private/tmp/11ty-873/node_modules/@11ty/eleventy/src/Engines/Nunjucks.js:410:14
[11ty] at Template._render (/private/tmp/11ty-873/node_modules/@11ty/eleventy/src/TemplateContent.js:514:28)
[11ty] at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
[11ty] Wrote 0 files in 0.03 seconds (v2.0.1)