webc icon indicating copy to clipboard operation
webc copied to clipboard

Computing data without render templates

Open bennypowers opened this issue 1 year ago • 6 comments

Instigating nunjucks example:

{% set thingies = someComponentVar | expensivelyGenerateImages %}
<ul>{% for thingy in thingies %}
  <li data-index="{{thingies.getIndex(thingy)}}">
    <img alt="{{thingy.alt}}" src="{{thingy.src}}">
  </li>{% endfor %}
</ul>

If I have an expensive-but-private computation to do within (not without) a component, I'd like to do it in a script block. I don't want to use a render template though, because I prefer to use one templating language wherever possible

straw example:

<script type="module" webc:data>
export const thingies = await expensivelyGenerateImages(someCompVar);
</script>

<ul>
  <li webc:for="thingy of thingies" :data-index="thingies.getIndex(thingy)">
    <img :alt="thingy.alt" :src="thingy.src">
  </li>
</ul>

In the straw example, the webc:data script has access to and runs in the component scope, but you can easily imagine a case where you'd want to reference the computed private prop multiple times, and memoizing the calc function is just cumbersome.

<script type="module" webc:data>
export const likes = await getWebmentionLikes(page.url);
export const many = likes.length > 12;
</script>

<template webc:nokeep webc:if="likes.length">

<h2>Likes</h2>

<ul :class="`webmentions likes ${many ? 'many' : ''}`">
  <li webc:for="mention of likes" class="webmention like">
    <a target="_blank" rel="noopener" :href="mention.author.url">
      <img :src="mention.author.photo" :title="mention.author.name">
    </a>
  </li>
</ul>

</template>

bennypowers avatar Apr 11 '23 05:04 bennypowers