Is component/partial composition possible?
See original GitHub issueI’ve read through quite a few of the open issues and PRs about “blocks” etc, but I’m unclear whether they solve my particular problem, or whether my problem is already achievable so please forgive me for logging this “issue” if it is.
I’m using Eleventy, a static site generator to build a website. It supports a lot of templating languages, but EJS] has been my favourite to work with in that it’s “just JavaScript”, except, I cannot figure out how to do component composition, or whether it’s at all possible. The EJS docs are… lacking.
What I want to achieve is similar to what you’d do in React or Vue with props.children
or <slot>
, where you compose components, but it would obviously be done with partials here.
For example, say I had a grid-item partial that accepted sizes it could render at, its tag name and “children”, something like:
<%- include('../grid-item', {
size: '50',
tag: 'li',
children: ANOTHER-INCLUDE,
}); %>
However, even the above example is a bit limiting, so what I’d really like to achieve is something like:
<%- include('../grid', {
tag: 'ul',
}, () => { %>
<%- include('../grid-item', {
size: '50',
tag: 'li',
}, () => { %>
<div>ANY MARKUP</div>
<% }); %>
<% }); %>
Is this possible? Am I approaching this from the wrong angle?
Eleventy supports a workaround for this with Paired Shortcodes for Nunjucks and Liquid, but both of those templating languages seem severely limited. Handlebars supports this via its @partial-block
syntax, but wrangling Handlebars to even remotely do what’s possible in EJS is excruciating.
Any help would be greatly appreciated.
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (1 by maintainers)
Another good use case example is a
container
component, which can be re-used within a header, main content modules and the footer to create a centered, max-width element within a full-bleed container, which in Vue would be created like this:and would be used in multiple components like so:
Thinking how Vue and React handle it, perhaps a closing tag syntax isn’t that bad 😊
It seems to me that using closing tag syntax could be a good way to go. You could also do it via a parameter passed to the same component file so that your opening and closing tags for a component remain together.
E.g
door
is just an example, I’m sure something more semantic could be thought of - I was just thinking of something that opens and closes. (Even self-close I guess)Then in the component file
grid/cell.ejs
you can have:Personally I think it’s nice being able to see all the code for a component in the same place without needing to have a separate
start
andend
file