Looping with Render Functions
Updated:
Unless you really like copying and pasting, you’re probably going to want to write some loops in your HTML templates.
Coming from template languages like Liquid or Nunjucks, you’ll probably start looking for a for
keyword, but WebC doesn’t have anything like that — at least, not yet.
Instead, you’ll want to write a render function.
A render function is just a <script>
tag with some special WebC attributes.
Inside the script tag is a function that returns a string.
That function gets executed and that string gets written into your markup.
For simple loops, the syntax feels a bit cumbersome. But since you are writing JavaScript, you can do much, much more with it than the looping constructs available to you in Liquid or Nunjucks.
Let’s start simple.
<ul>
<script webc:type="js" webc:is="template">
collections.all
.map(
(page) => `<li>
<a href="${page.url}">${page.data.title}</a>
</li>`
)
.join("");
</script>
</ul>
For this site, I created a custom component — collection-list.webc — that renders links to pages from a collection.
You pass it a tag name, and an optional limit, and it produces <article>
tags for each page in the collection.
<script webc:type="js" webc:is="template">
// Copy the collection because Array.prototype.reverse() reverses the array
// in-place, and we don't want to permanently reverse the collection, we just
// want to reverse it for this component.
let collection = [...$data.collections[tag]].reverse();
if (limit) collection = collection.slice(0, limit);
collection
.map(
(page) => `<article>
<a href="${page.url}">${page.data.title}</a>
<p>${page.data.description}</p>
</article>`
)
.join("");
</script>
This component is then used on the home page to render links out to all of the techniques listed here on the site.
<h2>Techniques</h2>
<collection-list tag="technique" limit="3"></collection-list>
So you can either just plop the render function down where you need it for an ad hoc loop, or you can wrap it up in a component that you can just drop in where you need it.