webc
webc copied to clipboard
Order of operations: slot content with WebC Transforms
So imagine a webc component named reverse. The idea is to take content from the default slot and reverse it. It would be used like so:
<reverse>
This is a test.
</reverse>
And the output would simply reverse that string. I tried doing this with Liquid, like so:
<template webc:type="11ty" 11ty:type="liquid">
{% capture content %}
<slot><p>Im the default slot.</p></slot>
{% endcapture %}
<p>
Content: {{ content }}
</p>
<p>
Content reversed: {{ content | split: "" | reverse | join: "" }}
</p>
</template>
The output was... unusual:
Content: This is a test.
Im the default slot.
Content reversed: >tols/<>p/<.tols tluafed eht mI>p<>tols<
It correctly captured the default slot, but then output the default text as if I had not passed any in. And then - oddly - despite the content variable being correct, when the split/reverse/join is called, it used the raw HTML.
You can see this here:
https://glitch.com/edit/#!/determined-honorable-porch?path=src%2F_includes%2F_components%2Freverse.webc%3A18%3A0
Just a guess: does the liquid template element get processed as Liquid before WebC? I think that's the issue. While rendering the WebC file it sees the Liquid element, processes it first as Liquid, then the Liquid output as WebC before returning execution to the rest of the file.
Does it help to capture only the inside of the <slot>?
<template webc:type="11ty" 11ty:type="liquid">
<slot>
{% capture content %}
<p>Im the default slot.</p>
{% endcapture %}
</slot>
<p>
Content: {{ content }}
</p>
<p>
Content reversed: {{ content | split: "" | reverse | join: "" }}
</p>
</template>
Oh interesting - I'm going to try now - Glitch is being a bit slow. :\
No go, if you view the Glitch url, I built a new version, reverse2, to test that, and I end up with:
This is a test.
Content:
I'm the default slot.
Content reversed: >p/<.tols tluafed eht m'I>p<
HMMMMMM, webc:type transforms do happen before WebC and slot resolution (as is by design).
So this:
{%- capture content %}<slot><p>Im the default slot.</p></slot>{%- endcapture %}
will capture <slot><p>Im the default slot.</p></slot>.
Unfortunately that also means that
<slot><p>{%- capture content %}Im the default slot.{%- endcapture %}</p></slot>
will capture Im the default slot.
Fortunately, the WebC data cascade does have access to (raw/unprocessed—read: not yet processed by WebC) slot content, so this will work:
<p>{%- capture content %}{{ slots.text.default | default: "Im the default slot." }}{%- endcapture %}</p>
(using liquid’s default filter to provide fallback content)
We use the above approach in the provided syntax highlighter WebC component https://github.com/11ty/eleventy-plugin-syntaxhighlight/blob/ac92151c42996faef19650f34f54a77e4ac210f2/syntax-highlight.webc#L13
Zach, I was actually going to file an ER for this - slot.text.default. Does this mean I can access slots in my code? slot.text.NAMEOFSLOT?
yeah, 100%. Just note that it is raw ~~text~~ content, not processed WebC
Hmm. So imagine in the parent I have
I can confirm my simpler, reverse-er webc works:
<template webc:type="11ty" 11ty:type="liquid">
<slot><p>Im the default slot.</p></slot>
<p>
Content reversed: {{ slots.text.default | split: "" | reverse | join: "" }}
</p>
</template>
However, if I do: <reverse3></reverse3> (see first post w/ link to glitch), the result is empty. Shouldn't it reverse the text I used as a default?