Step 4. Templating with WebC
So, you have a sort of website that's working which goes to show you how little you actually need of a lot of the cruft of various software. It's not much of one though, it is just some disparate pieces of HTML. You probably want to add the rest of an HTML document around it, attach styles, JS, maybe even one of those annoying corpo JS frameworks like React or one of the good ones like Svelte.
There are some great choices for templating in 11ty and I personally was a longtime user of Nunjucks. However, I only use two types of templates nowadays in 11ty, Markdown and WebC. Markdown is great for writing and reading by humans or machines and is ideal for translating onto the web. WebC is a first class vanilla component framework that once you try, you'll never want to use any other option.
From here on out, I'll only be using WebC for templating. I
have added a recommended extension for VSCode to help with
WebC syntax highlighting and snippets at this commit. Let's
create that master template we talked about earlier by
creating a special file known as a layout. Layouts in 11ty
are stored in a special folder named /_includes. Create
a file named root.webc in that folder. To use this layout,
we need to hook up the first party WebC plugin and assign
this new layout to any template we want to use it.
We install the plugin with Bun using
bun i -D @11ty/eleventy-plugin-webc and then add it to
the 11ty config with the line:
import pluginWebc from "@11ty/eleventy-plugin-webc";
...
eleventyConfig.addPlugin(pluginWebc);
Let's try out the layout by going back to our index.md
and adding the Front Matter:
---
layout: root.webc
title: Home
---
Now type anything into the root.webc file. Let's boot up the dev server and see what happens. Oh, we see the text we typed in the layout but nothing from the template. That's because we need to add a slot for the content in the layout. We'll be running through some WebC features as we go but understand that WebC is just HTML.
Into the root.webc file, add the following:
<template @raw="content" webc:nokeep></template>
Now in the browser if the dev server is still running, you
should see the content from the index.md file. We've
taken the template element and called the @raw directive
with the special "content" argument that will render child
templates. <template> elements are a great element to use
for this purpose as they won't render anything into the DOM
themselves, and the webc:nokeep attribute tells 11ty to
not keep the template element in the final output, only the
child content.
Let's add the rest of the simple HTML body indo root.webc:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<template @raw="content" webc:nokeep></template>
</body>
</html>
Now you can see that /_site/index.html file has a full
HTML document structure around it. You should add this
layout to Front Matter of any other templates for now.
While I'm in here I'll move title into the Front Matter
as well.
For some of these pages, we might want full control over every last bit of HTML displayed. For these blog articles, I think I would rather have a default template with standard items like titles and metadata. So let's create another layout to use for these blog articles.
Create a file named blog.webc in the /_includes folder
with the following content:
---
layout: root.webc
---
<article>
<h1 @text="title"></h1>
<template @raw="content" webc:nokeep></template>
<footer>
Tags: <blog-tag webc:for="tag of tags" @text="tag" />
</footer>
</article>
Wow! Simple but cool, yeah? What's the \<blog-tag\>
element? I don't recommend using spans or divs so it's a
custom element I made up. This syntax is nice but WebC
has a lot more substance than just nice syntax. In the
next step we'll look at WebC components.
Before we leave let's clean refactor one thing. If you recall
in the data article, we could use directory data files. Let's
do that here, creating /blog/blog.json with:
{
"tags": ["blog"],
"layout": "blog.webc"
}
Now the blog layout will be assigned to all these files and we can delete the Front Matter entry. If inside of an article we have a Front Matter entry like:
---
title: A Lunch
tags: [lunch]
---
then the article will have the tags "blog and "lunch."