Allow renderFile or equivalent to fail silently if file does not exist #4144
Replies: 5 comments
-
|
Good suggestion! How about |
Beta Was this translation helpful? Give feedback.
-
eleventy.config.jsconst fs = require("node:fs");
const path = require("node:path");
const { EleventyRenderPlugin } = require("@11ty/eleventy");
/**
* @param {import("@11ty/eleventy/src/UserConfig")} eleventyConfig
* @returns {ReturnType<import("@11ty/eleventy/src/defaultConfig")>}
*/
module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(EleventyRenderPlugin);
eleventyConfig.addAsyncShortcode("renderFileIfExists", async function (filename, data={}) {
filename = path.join("./src/_includes", filename);
if (fs.existsSync(filename)) {
return eleventyConfig.javascriptFunctions.renderFile(filename, data);
}
return "";
});
return {
dir: {
input: "src",
output: "www",
}
};
};src/cats.njk---
title: Cats
---
{%- set desc = "tags/" + page.fileSlug + ".md" -%}
{%- renderFileIfExists desc %}
Cat things here.src/dogs.njk---
title: Dogs
---
{%- set desc = page.fileSlug + ".md" -%}
{% renderFileIfExists desc %}
Dog things here.src/_includes/tags/cats.md# CATS LIVE HERE
They _sometimes_ catch mice.OUTPUTwww/cats/index.html<h1>CATS LIVE HERE</h1>
<p>They <em>sometimes</em> catch mice.</p>
Cat things here.www/dogs/index.htmlDog things here.DIRStree -A --gitignore
.
├── eleventy.config.js
├── package-lock.json
├── package.json
├── src
│ ├── _includes
│ │ └── tags
│ │ └── cats.md
│ ├── cats.njk
│ └── dogs.njk
└── www
├── cats
│ └── index.html
└── dogs
└── index.html
6 directories, 8 files |
Beta Was this translation helpful? Give feedback.
-
|
If you want a more eleventy.config.js (snippet)const fs = require("node:fs");
eleventyConfig.addFilter("fsExists", function (filename) {
return fs.existsSync(filename);
});src/cats.njk{%- set desc = "src/_includes/tags/" + page.fileSlug + ".md" -%}
{% if desc | fsExists %}
{% renderFile desc %}
{% endif %}A bit more verbose, but possibly more flexible. |
Beta Was this translation helpful? Give feedback.
-
|
Yes! I think the filter approach gives more utility for other cases.
Though it’s hard to resist the first approach and calling the shortcode
`renderFileGently`
…On Sat, Sep 16, 2023 at 19:43 Peter deHaan ***@***.***> wrote:
If you want a more .addFilter() approach:
eleventy.config.js (snippet)
const fs = require("node:fs");
eleventyConfig.addFilter("fsExists", function (filename) {
return fs.existsSync(filename);
});
src/cats.njk
{%- set desc = "src/_includes/tags/" + page.fileSlug + ".md" -%}{% if desc | fsExists %}
{% renderFile desc %}{% endif %}
A bit more verbose, but possibly more flexible.
—
Reply to this email directly, view it on GitHub
<#3051 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAKPYI4QKTRUR7AXZ2QZ6LLX2Y2TPANCNFSM6AAAAAA43BTVC4>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
|
@thedamon You could do some hybrid solution that uses the shortcode but still lets you use the filter for other things (like checking for global data files or whatever): eleventyConfig.addFilter("file_exists", function (filename, throwOnMissing=false) {
const exists = fs.existsSync(filename);
if (throwOnMissing && !exists) {
throw new Error(`Missing file: "${filename}"`);
}
return exists ? filename : false;
});
eleventyConfig.addAsyncShortcode("renderFileIgnoreMissing", async function (filename, data={}) {
const fileExists = eleventyConfig.getFilter("file_exists");
if (!!fileExists(filename)) {
return eleventyConfig.javascriptFunctions.renderFile(filename, data);
}
return "";
});USAGEA:
{%- set descA = ("src/_includes/tags/" + page.fileSlug + ".md") | file_exists -%}
{%- renderFileIgnoreMissing descA %}
---
B:
{%- set descB = ("src/_includes/tags/" + page.fileSlug + ".md") | file_exists() -%}
{% if descB %}
{% renderFile descB %}
{% endif %}
---
C:
{%- set descC = ("src/_includes/tags/" + page.fileSlug + ".md") | file_exists(true) -%}
{% renderFile descC %}Both example A and B should work since we're using our custom UPDATE: Sorry, I re-read this and it's a bit of a mess. Probably worth explaining this filter: eleventyConfig.addFilter("file_exists", function (filename, throwOnMissing=false) {
const exists = fs.existsSync(filename);
if (throwOnMissing && !exists) {
throw new Error(`Missing file: "${filename}"`);
}
return exists ? filename : false;
});Basically the probably-confusingly-named |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Is your feature request related to a problem? Please describe.
I want to pull in files dynamically, associating markdown descriptions of taxonomies and other things like so:
In this scenario, though, if the tag does not exist eleventy will fail to build.
Describe the solution you'd like
It seems potentially useful to be able to opt not to fail if the file is not there today. Probably best would be an additional shortcode that has a try/catch in it:
{% renderFileIfExists desc %}Nunjucks as an option in include:
{% include "missing.html" ignore missing %}Describe alternatives you've considered
A simple way to check the existence of the file in another variable or maybe more helpfully overall adding a custom
{% try %}block to supported templating languages then I could instead doAdditional context
No response
Beta Was this translation helpful? Give feedback.
All reactions