11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.
https://www.11ty.dev/
MIT License
17.1k stars 493 forks source link

addJavaScriptFunction "render" interferes with .11ty.js templates (e. g. with tagNameFile: "render") #2454

Open raffaelj opened 2 years ago

raffaelj commented 2 years ago

I tried to use the latest feature of tagNameFile: "render" with the render plugin and and got confusing error messages. I digged a bit deeper and found out, that if a javascript function was added with the name "render", it overwrites the default render behavior.

To Reproduce

with render plugin

.eleventy.js:

eleventyConfig.addPlugin(EleventyRenderPlugin,{
    tagNameFile: "render",
});

class.11ty.js:

module.exports = class {
    render(data) {
        return `<p>content from class.11ty.js</p>`;
    }
}

error:

[11ty] 1. Having trouble rendering 11ty.js template ./class.11ty.js (via TemplateContentRenderError)
[11ty] 2. filePath.split is not a function (via TypeError)
...

My workaround is to use the default renderFile or @render for now.

without render plugin

.eleventy.js:


//     eleventyConfig.addJavaScriptFunction('render', function () {
//         return `<p>content from addJavaScriptFunction - render</p>`;
//     });

    eleventyConfig.addShortcode('render', function () {
        return `<p>content from addShortcode - render</p>`;
    });

text.11ty.js:

module.exports = `<p>content from text.11ty.js</p>`;

class.11ty.js:

module.exports = class {
    render(data) {
        return `<p>content from class.11ty.js</p>`;
    }
}

The output of text.11ty.js and class.11ty.js is now <p>content from addShortcode - render</p>.

Expected behavior

Don't overwrite the render function OR check against a list of known reserved names and throw an error, if a user could break 11ty with a shortcode or the render plugin.

Environment:

zachleat commented 2 years ago

Yeah render should probably be reserved and throw an error message there. We also didn’t use render by default as it conflicts with Liquid.js too https://liquidjs.com/tags/render.html#sidebar