mde / ejs

Embedded JavaScript templates -- http://ejs.co
Apache License 2.0
7.74k stars 843 forks source link

Can't disable recursiveness of locals? #553

Open clshortfuse opened 3 years ago

clshortfuse commented 3 years ago

I'm trying to build some partial files. Some of my partials have a long list of options.

For example, let's say a button partial has something like 20 options, eg: ['background', 'color', 'width', 'height', 'text', ...]. If you don't use locals, then you have to include every variable possible or else they would be undefined. It wouldn't be sane to have to write every option every time you want to include it:

<button style="<%- width ? `width:${width}px;`: '' %>"><%= text  -%></button>
include('./button.ejs', {
  background: undefined, color: undefined, width: undefined, height: undefined, text: 'hello',
});

If you use locals, then you can do:

<button style="<%- locals.width ? `width:${locals.width}px;`: '' %>"><%= button.text  -%></button>
include('./button.ejs', { text: 'hello' });

The problem arises when you are using an include inside another include. Let's say dialog.ejs looks like this:

<dialog style="<%- locals.width ? `width:${locals.width}px;`: '' %>">
  <%- include('./button.ejs', { text: 'hello' }) -%>
</dialog>

Because variable inheritance is forced, and not optional, that means both <dialog> and <button> with both have the same value in locals.width. That means the <button> will also get the same width as the dialog. The only alternative I've found is to either create unique variable names for each and every partial (eg: buttonText, dialogText, buttonWidth, etc), though that gets really convoluted. Also, it means parameters of each partials are no longer unique, requiring a new JSDoc for each and every partial, instead of something that can be shared.

It seems that instead of include being called a function in an isolated scope, it's instead embedding the called function inside itself with a closure. (ie: dialogFn executes buttonFn within itself, instead of calling a function and only caring about the return). Basically, I would want every include to be static. The concept of local would be just that, just local to the function itself, not globally inheriting all the variables that came before it (ie: "Functional Programming"), If I need to pass down a function, I would do that imperatively.

I'm not sure if I'm missing something in the CLI, or options, but it really doesn't currently seem possible.

jimbo8098 commented 3 years ago

I would love this as well, I'm experiencing the same issue here.

dlueth commented 3 years ago

Experiencing this as an issue as well.

yelhouti commented 2 years ago

Same here...