Replies: 4 comments 3 replies
-
import type { EtaConfig } from "eta/dist/types/config.js";
import type { AstObject, TemplateObject } from "eta/dist/types/parse.js";
import type { TemplateHelperOpts } from "../template.js";
const contentRegex = /^content\s*\(\s*"([^]*)"\s*\)\s*\${$/;
const slotRegex = /^slot\s*\(\s*"([^]*)"\s*\)(\s*\${)?$/;
const plugin = {
processFnString: (fnStr: string) => {
return `it[Symbol.for("slotsPlugin")]=it[Symbol.for("slotsPlugin")]||{};${fnStr}`;
},
processAST: (ast: Array<AstObject>, _env: EtaConfig) => {
for (const token of ast) {
//Make sure it's a template object
if (typeof token === "string") continue;
//Make sure it's an evaluate tag
if (token.t !== "e") continue;
const val = token.val.trim();
//Its a @content "name"
if (contentRegex.test(val)) {
const slotName = "_" + contentRegex.exec(val)![1].replaceAll(/\W/g, "");
token.val = `
it[Symbol.for("slotsPlugin")]["${slotName}"] = tR;
tR = "";
___slot${slotName}();
[tR, it[Symbol.for("slotsPlugin")]["${slotName}"]] = [it[Symbol.for("slotsPlugin")]["${slotName}"], tR.trim()];
function~___slot${slotName} () {
`
.replace(/\s/g, "")
.replace("~", " ");
} else if (slotRegex.test(val)) {
const match = slotRegex.exec(val)!;
const slotName = "_" + match[1].replaceAll(/\W/g, "");
const hasDefault = Boolean(match[2]);
token.val = `
if(it[Symbol.for("slotsPlugin")]["${slotName}"]) {
tR += it[Symbol.for("slotsPlugin")]["${slotName}"];
} ${
hasDefault
? `
else {
___slotdefault${slotName}() ?? "";
}
function~___slotdefault${slotName} () {`
: ""
}
`
.replace(/\s/g, "")
.replace("~", " ");
}
}
return ast;
}
};
export default plugin; EDIT: Fixed regex for slot name Needed slots in my app, made this, enjoy. Don't really care to make this a plugin myself as I don't want to deal with making sure its compatible on all browsers since I'm using it on nodejs. If anyone wants to make it into a plugin, just plop a link to this comment somewhere in the readme. |
Beta Was this translation helpful? Give feedback.
-
awesome, thanks for sharing! |
Beta Was this translation helpful? Give feedback.
-
For now, I think this is outside the scope of the project, so I'm going to convert this to a discussion. But I think it would be awesome if someone were to implement it as a plugin! |
Beta Was this translation helpful? Give feedback.
-
Just curious...why doesn't this suggestion from the original post already work now? Include returns a string, right? Wouldn't passing a string to the body variable in the model work? What's missing to make that happen?
|
Beta Was this translation helpful? Give feedback.
-
Is your feature request related to a problem? Please describe.
i'm using eta in a little static-site build tool that i'm writing. it'd be nice to be able to use nested includes or ideally, slots. maybe you already can? does this even seem feasible?
it would help in situations where you want to define a shared layout for elements within a page. even it eta's current state, i expected to be able to do something like:
Describe the solution you'd like
something syntactically similar to svelte slots, but not as wild. if even the above worked, that would be nice, but aspirationally:
a third argument to the template that is a string or a function producing a string that eta can parse and insert into the correct slots in the variables dictionary.
Describe alternatives you've considered
the approach outlined in the first section, nested includes and variables. i would go so far as to say that if that worked, it would probably be enough. and i could write my own preprocessing to produce that from something like:
Additional context
not sure, but happy to provide any. long live html.
Beta Was this translation helpful? Give feedback.
All reactions