Series: 11ty Theme
tl;dr: How I navigated adding sidebars to the sites, with some repeating on both sites and some unique per site.
Series Description: However many years later, I have actually done something resembling completing the design of this site using eleventy aka 11ty! I'm sure there are still more things I'll decide to change later, but the general idea I'm pretty happy with. This series describes some of the main challenges I faced. You can navigate other posts in the series using the list of links in the sidebar.
For this post, I'm going to look at the sidebars.
Sidebars were relatively simple once I had a basic grasp of the templating engine, but did get slightly more complicated because there were things that I wanted to be on both sites - the posts by tag and posts by year lists - and then some other things where I wanted freedom to add one or more extras blocks per site. Here's what I came up with.
Shared Theme's Template
In the includes/main.njk file, I specified the sidebar:
<div class="sidebar">
{% set sidebarBlocks = collections.sidebar %}
{% include "block-sidebars.njk" %}
{% include "block-series-list.njk" %}
{% include "block-tags-list.njk" %}
{% include "block-year-list.njk" %}
</div>
This pulls first from anything unique to this site that gets added to the sidebar collection, and the block-sidebars template displays those. The other three are the same blocks that appear in both sites using the theme.
Site-Specific
In the shared theme, the block-sidebars template looks like this:
{# Flexible sidebars that can be added for any site by adding content of the tag "sidebar." #}
{% for sidebar in sidebarBlocks %}
<aside class="sidebar-block" aria-label={{ sidebar.data.title }}>
<h2>{{ sidebar.data.title }}</h2>
{{ sidebar.content | safe }}
</aside>
{% endfor %}
This grabs everything from the sidebarBlocks variable, which I just set to the sidebar collection in the main template file above, and then shows them one at a time with an aside and a heading template.
How does the sidebar collection get created? That is simply every piece of content that has a tag of "sidebar" on it. To help simplify that, in each site, I have a folder "sidebar-blocks" under "content", alongside "posts," and in that folder is a file called sidebar-blocks.11tydata.js that automatically applies the tag as well as denies setting up a permalink (a dedicated page) to everything put into that folder:
export default {
tags: "sidebar",
permalink: false,
};
Each individual sidebar file can then be really simple, like the About sidebar on this site:
---
title: About
---
<div class="sidebar-container">
<p>I'm Ryan Robinson. I've been working in technology for my adult life. I am now primarily focused on Drupal website development. On this site I document some of the work I've done, whether within a full-time job, freelance work, volunteering, or as a personal side project.</p>
</div>
That's as intuitive as possible going forward to edit and create new site-specific sidebar blocks.
Series
Next up is the the series block. This one shows all other posts that in the same series as the current post being viewed.
{# Block showing other pages in the same series as the current page. #}
{% if series %}
<aside class="sidebar-block" aria-labelledby="posts-in-series-label">
<h2 id="posts-in-series-label">Posts in Series</h2>
<p>Series: {{ series }}</p>
<ol class="series-list">
{% for post in collections.posts | postsWithMetadata("series", series) %}
<li><a href="{{ post.url }}">{{ post.data.title }}</a></li>
{% endfor %}
</ol>
</aside>
{% endif %}
The key filter for that one is simple, taking all posts and then filtering it down to only those that have a series matching the current page's series.
Tag Lists
Finally, year lists and tag lists are the same idea, but filtering on different metadata.
Here's the tags-list:
{# Common snippet used for tags page and sidebar snippet #}
{%- css %}{% include "11ty-theme/css/tags-list.css" %}{% endcss %}
<ul class="tags-list">
{% for tag in collections | getKeys | filterTagList %}
{% set tagUrl %}/tags/{{ tag | slugify }}/{% endset %}
<li><a href="{{ tagUrl }}" class="post-tag"{% if tagDescriptions[tag] %} title="{{ tagDescriptions[tag] }}"{% endif %}>{{ tag }}</a> ({{ collections[tag].length }})</li>
{% endfor %}
</ul>
The filter in use, filterTagList, was already covered in the previous post about generating post lists.
Years List
And here's the similar idea for the years-list:
{# Common snippet used for years page and sidebar snippet #}
{%- css %}{% include "11ty-theme/css/tags-list.css" %}{% endcss %}
<ul class="tags-list">
{% for year, count in collections.postsByYear.keys | dictsort(true, 'key') | reverse %}
{% set yearUrl %}/{{ year }}/{% endset %}
<li><a href="{{ yearUrl }}" class="post-tag">{{ year }}</a> ({{ count }})</li>
{% endfor %}
</ul>
That's grabbing all posts, by their year only, and sorting it into a paged result.
Previous: Filtered Post Lists
Next: Nested Pagination