Skip to main content

Tagged “11ty”

Excerpts for Eleventy, by Keith Carangelo

Recently I updated this website’s git repository README to include a summary of my approach to supporting post excerpts.

I define an initial part of a post as the excerpt by adding a separator string between it and the remaining content. Then in my posts list I grab 11ty’s post.page.excerpt and pass that through a custom markdown-parsing filter.

This works pretty well but sometimes it’s a bit inflexible that the excerpt has to be part of the post. Sometimes you might want to say something different, or shorter and snappier in the excerpt.

Top rankin’

In my recent post Website updates I said:

I’ve added myself to 11ty’s community and am now listed as an Eleventy author. I hope that some day I’ll find that fuzzylogic.me has been added to 11ty’s Speedlify Leaderboard too – that’d be cool!

Well, about a week ago I noticed that I have been added to 11ty’s Speedlify Leaderboard and not only that I’ve gone straight in at the very respectable rank of #23. I’m among some really talented company there so I’m proud of that!

Website updates

I’ve recently been updating my website over a series of nights and weekends. The changes aren’t very noticeable to the eye but involved some careful modernisation and streamlining of back-end features and technology, plus improvements to accessibility and performance. I’m really happy to have made them.

WebC

WebC, the latest addition to the Eleventy suite of technologies, is focused on making Web Components easier to use. I have to admit, it took me a while to work out the idea behind this one, but I see it now and it looks interesting.

Here are a few of the selling points for WebC, as I see them.

With WebC, web components are the consumer developer’s authoring interface. So for example you might add a badge component into your page with <my-badge text='Lorem ipsum'></my-badge>.

Using web components is great – especially for Design Systems – because unlike with proprietary component frameworks, components are not coupled to a single technology stack but rather are platform and stack-agnostic, meaning they could be reused across products.

From the component creator perspective: whereas normally web components frustratingly require writing accompanying JavaScript and depending on JavaScript availability even for “JavaScript-free” components, with WebC this is not the case. You can create “HTML-only” components and rely on them to be rendered to screen. This is because WebC takes your .webc component file and compiles it to the simplest output HTML required.

WebC is progressive enhancement friendly. As mentioned above, your no-JS HTML foundation will render. But going further, you can also colocate your foundational baseline beside the scripts and CSS that enhance it within the same file.

This ability to write components within a single file (rather than separate template and script files) is pretty nice in general.

There are lots of other goodies too such as the ability to scope your styles and JavaScript to your component, and to set styles and JS to be aggregated in such a way that your layout file can optionally load only the styles and scripts required for the components in use on the current page.

Useful resources:

Use Eleventy templating to include static code demos

Here’s a great tutorial from Eleventy guru Stephanie Eckles in which she explains how to create a page that displays multiple code demos, similar to SmolCSS.dev.

It’s interesting that Stephanie uses 11ty shortcodes over other 11ty templating options and that she sometimes declares a variable (via Nunjucks’s set) at the top of the page then intentionally reuses it unchanged in repeated shortcode instances… the example being times where you want to illustrate the same HTML code (variable) being styled differently in progressive demos.

I also like the Open in CodePen feature and section on scoped styling.

Reusable code snippets and components in Eleventy

There are (at least) three cunning ways in Eleventy to get “reusable snippet” or “reusable component” functionality.

  1. Nunjucks’s include: Great for just including a common, static element in your template, say a header or footer partial. (Note that while you can set a variable just before your include line to make that variable available to the included partial, it’s not really “passing in” and scoping the variable like a parameter, so it’s best to reserve include for simple stuff.)
  2. Nunjucks’s macro: Takes things up a notch by supporting passing in parameters which are then locally scoped. You could use this to create a simple component. See Trys Mudford’s article Encapsulated 11ty Components.
  3. 11ty Shortcodes and Named Shortcodes: Shortcodes feel to me pretty much like a wrapper for macro, whilst also supporting the inclusion of npm packages and the use of async functions. However with Named Shortcodes, unlike macro you can also pass in a block of content (rather than arguments alone). This would be handy for any component or layout into which you nest lots of varied content (such as a Stack, for example). See 11ty docs on paired shortcodes for more details.

Hat tip to Jérome Coupé who recently tweeted on this topic and prompted me to gather my thoughts too.

Manage Design Tokens in Eleventy

One interesting aspect of the Duet Design System is that they use Eleventy to not only generate their reference website but also to generate their Design Tokens.

When I think about it, this makes sense. Eleventy is basically a sausage-machine; you put stuff in, tell it how you want it to transform that stuff, and you get something new out the other end. This isn’t just for markdown-to-HTML, but for a variety of formatA-to-formatB transformation needs… including, for example, using JSON to generate CSS.

Now this is definitely a more basic approach than using a design token tool like StyleDictionary. StyleDictionary handles lots of low-level stuff that would otherwise be tricky to implement. So I’m not suggesting that this is a better approach than using StyleDictionary. However it definitely feels pretty straightforward and low maintenance.

As Heydon Pickering explains, it also opens up the opportunity to make the Design Tokens CMS-editable in Netlify CMS without content editors needing to go near the code.

So you’d have a tokens.json file containing your design tokens, but it’d be within the same repo as your reference website. That’s probably not as good as having the tokens in a separate repo and making them available as a package, but of course a separate 11ty repo is an option too if you prefer.

For a smaller site at least, the “manage design tokens with 11ty” is a nice option, and I think I might give it a try on my personal website.

Duet Design System

Here’s a lovely Design System that interestingly uses Eleventy for its reference website and other generated artefacts:

We use Eleventy for both the static documentation and the dynamically generated parts like component playgrounds and design tokens. We don’t currently use a JavaScript framework on the website, except Duet’s own components.

I find Duet interesting both from the Design System perspective (it contains lots of interesting component techniques and options) but also in terms of how far 11ty can be pushed.

Favourite Eleventy (11ty) Resources

Here are my current go-to resources when building a new site using Eleventy (11ty).

Build an Eleventy site from scratch by Stephanie Eckles. As the name suggests, this is for starting from a blank canvas. It includes a really simple and effective way of setting up a Sass watch-and-build pipeline that runs alongside that of Eleventy, using only package.json scripts rather than a bundler.

Eleventy Base Blog from 11ty. If rather than a blank canvas you want a boilerplate that includes navigation, a blog, an RSS feed and prism CSS for code block styling (among other things) then this is a great option. Of course, you can also just cherry-pick the relevant code you need, as I often do.

Eleventy Navigation Plugin. This allows you to set a page or post as a navigation item. It handily supports ordering and hierarchical nesting (for subnavigation). You can then render out your navigation from a layout in a one-liner or in a custom manner.

Eleventy Cache Assets Plugin. This is really handy for caching fetched data so as not to exceed API limits or do undue work on every build.

11ty Netlify Jumpstart is another from Stephanie Eckles but this time a “quick-start boilerplate” rather than blank canvas. It includes a minimal Sass framework, generated sitemap, RSS feed and social share preview images. The About page it generates contains lots of useful info on its features.

forestry.io settings for 11ty Base Blog and forestry.io settings for Hylia (Andy Bell’s 11ty starter)

Add Netlify CMS to an 11ty-based website

All my posts tagged “11ty”

More to follow…

Daniel Post shared a really cool performance-optimisation trick for Eleventy on Twitter the other day. When statically generating your site you can loop through your pages and, for each, use PurgeCSS to find the required CSS, then inline that into the <head>. This way, each page contains only the CSS it needs and no more!

Check out the code.

I’ve just installed this on my personal site. I was already inlining my CSS into the <head> but the promise of only including the minimum CSS that each specific page needs was too good to resist.

Turned out it was a breeze to get working, a nice introduction to Eleventy transforms, and so far it’s working great!

Color Theme Switcher (on mxb.dev)

Max shows us how to build a colour theme switcher to let users customise your website. He uses a combination of Eleventy, JSON, Nunjucks with macros, a data attribute on the html element, CSS custom properties and a JavaScript based switcher.

Thanks, Max!

Online Résumé (maxboeck on Github)

A beautiful, responsive, print-friendly résumé template from Max.

Some points of note:

  • Accessible (WCAG AA)
  • uses the h-resume Microformat
  • uses a Spellcheck Linter
  • Search Engine Optimized (meta, JSON-LD, etc...)
  • Built with Eleventy
  • Netlify-ready (although hosting choice is up to you)
  • Critical CSS Inlined
  • Print Styles

Emergency Website Kit (Max Böck)

In cases of emergency, many organizations need a quick way to publish critical information. But existing (CMS) websites are often unable to handle sudden spikes in traffic.

Fantastic effort by Max Böck here, stepping up during the COVID-19 pandemic to provide this Eleventy template for organisations to use to publish critical information as lean, resilient, static HTML pages.

Flexible tag-like functionality for custom keys in Eleventy

I have an open-source, Eleventy-based project where the posts are restaurants, each of which is located in a particular city, and contributors to the repo can add a new restaurant as a simple markdown file.

I just had to solve a conundrum wherein I wanted a custom front matter key, city, to have similar features as tags, namely:

  1. it takes arbitrary values (e.g. Glasgow, or London, or Cañon City, or anything a contributor might choose);
  2. there is a corresponding cityList collection;
  3. there is a page which lists all cities in the cityList collection as links; and
  4. there’s a page for each city which lists all restaurants in that city (much like a “Tagged Glasgow” page).

You could be forgiven for asking: why didn’t I just implement the cities as tags? I could have tagged posts with “glasgow”, or “edinburgh” for example. Well, here was my rationale:

  • for cities, I need the proper, correctly spelled, spaced and punctuated name so I can display it as a page title. A lowercased, squashed together “tag” version wouldn’t cut it;
  • I list “all tags” elsewhere and wouldn’t want the cities amongst them. Although Eleventy allows you to filter given tag values out, in this case that would be a pain to achieve because the city values are not known up front;
  • Lastly it just felt right for ease of future data manipulation that city should be a separate entity.

This task was a bit of a head-scratcher and sent me down a few blind alleys at first. Rightly or wrongly, it took me a while to realise that only all posts for tag values are automatically available as collections in Eleventy. So any other collections you need, you have to DIY. Once I worked that out, I arrived at a strategy of:

implement all the requisite functionalty on tags first, then emulate that functionality for my custom key.

First port of call was the Eleventy Tag Pages tutorial. That showed me how to use the existing “collection for each tag value” to create a page for each tag value – the “All posts tagged with X” convention. (Here’s an example on this site.)

I then referenced the eleventy-base-blog repo which takes things further by creating a page which lists “all tags”. To achieve this you first need to create a custom tagList collection, then you create a page which accesses that new collection using collections.tagList, iterates it and displays each tag as a link. Each tag link points to its corresponding “All posts tagged with X” page we created in the step above.

So now I had everything working for tags. Next step: emulate that for cities.

Here’s what I ended up doing:

Create new file _11ty/getCityList.js

module.exports = function(collection) {
  let citySet = new Set();
  collection.getAll().forEach(function(item) {
    if( "city" in item.data ) {
      let city = item.data.city;
      citySet.add(city);
    }
  });

  return [...citySet];
};

Then add the following to .eleventy.js

// Create a collection of cities
eleventyConfig.addCollection("cityList", require("./_11ty/getCityList"));

// Create "restaurants in city" collections keyed by city name
eleventyConfig.addCollection("cityCollections", function(collection) {
  let resultArrays = {};
  collection.getAll().forEach(function(item) {
    if(item.data["title"] && item.data["city"]) {
      if( !resultArrays[item.data["city"]] ) {
        resultArrays[item.data["city"]] = [];
      }
      resultArrays[item.data["city"]].push(item);
    }
  });
  return resultArrays;
});

Next, create new file cities-list.njk:

---
permalink: /cities/
layout: layouts/home.njk
---
<h1>All Cities</h1>

<ul>
{%- for city in collections.cityList -%}
  {% set cityUrl -%}/cities/{{ city }}/{% endset %}
  <li><a href="{{ cityUrl | url }}">{{ city }}</a></li>
{%- endfor -%}
</ul>

Finally, create new file posts-in-city.njk:

---
renderData:
  title: Restaurants in “{{ city }}”
pagination:
  data: collections.cityList
  size: 1
  alias: city
permalink: /cities/{{ city | slug }}/
---
<h1>Restaurants in {{ city }}</h1>

{% set postslist = collections.cityCollections[ city ] %}
{% include &#39;postslist.njk&#39; %}

And that’s a wrap! Eleventy will do the rest when it next runs, creating for each city a page which lists all restaurants in that city.

Footnote: I should acknowledge this 11ty Github issue in which Ed Horsford was trying to do something similar (create a separate tags network) leading to Zach Leatherman pitching in with how he created noteTags for his website’s Notes section. That led me to Zach’s website’s repo on Github, specifically .eleventy.js and tag-pages.njk, without which I wouldn’t have found my way.

From dynamic to static

“I’ll just make a few small tweaks to my website…” said I. Cut to three sleep-deprived days later and I’ve rebuilt it, SSG/JAMstack-stylee with Eleventy and Netlify and entirely re-coded the front-end. Silly, but so far so good, and it’s greasy fast!

So yes, I’ve just updated my website from being a dynamic, LAMP-stack affair which used Perch CMS and was hosted on Linode to being statically-generated using Eleventy and hosted on Netlify.

It mostly went smoothly. And the environmental and continuous deployment boilerplate that Netlify provide are fantastic, and will be a real time-saver over my current “set up and maintain a Linode server” approach.

In terms of challenges and troubleshooting, I did have to find a solution to the issue of FOUT on repeat visits. It seems this was happening as a result of Netlify’s interesting approach to asset caching which works well for most requirements but wasn’t so great for self-hosted webfonts. My solution was to add specific headers for .woff and .woff2 files in my application’s Netlify config file.

See all tags.

External Link Bookmark Note Entry Search