Creating a List of Direct Child Pages in Eleventy
This website uses index pages that provide a list of direct child pages. To do so, it makes use of eleventyNavigation together with key–parent relations set up in the front matter. The list of subpages can be rendered to HTML using Liquid code, a WebC component, or an Eleventy Shortcode written in JavaScript.
Liquid Template
The Liquid code below compiles the list of child pages of the current page. Title and description are taken from each page’s front matter, the filter md renders the Markdown markup to HTML. This code could be placed in a separate file (partial) and included using the Liquid include tag:
{%- assign navPages = collections.all | eleventyNavigation: eleventyNavigation.key -%}
{%- if navPages.size > 0 %}
<dl>
{%- for child in navPages %}
<dt><a href="{{ child.url | url }}">{{ child.data.title | md }}</a></dt>
<dd><p>{{ child.data.description | md }}</p></dd>
{%- endfor %}
</dl>
{% endif -%}Eleventy Shortcode
An alternative approach would be to define an Eleventy shortcode. Front matter data is not available to shortcodes and therefore has to be passed to the shortcode. The listing below contains the implementation of a shortcode subpagesIndex that accepts the nodes as well as the key:
eleventyConfig.addShortcode('subpagesIndex', async function (nodes, key) {
const eleventyNavigation = eleventyConfig.getFilter('eleventyNavigation');
const subpages = eleventyNavigation(nodes, key);
if (subpages.length > 0) {
const md = eleventyConfig.getFilter('md');
const url = eleventyConfig.getFilter('url');
let subpagesHTML = '';
subpages.forEach((page) => {
subpagesHTML += `\
<dt><a href="${url(page.url)}">${md(page.data.title)}</a></dt>
<dd><p>${md(page.data.description)}</p></dd>\n`
;
});
return `<dl>\n${subpagesHTML}</dl>\n`;
}
});The shortcode can be used in a Liquid template as follows:
{% subpagesIndex collections.all, eleventyNavigation.key %}WebC Component
The listing below shows a solution based on a WebC component that renders a list of the current page’s subpages. The file subpages-index.webc has to be put into the _components directory which is located in the project’s root directory:
<script webc:setup>
const currentKey = getCollectionItem(collections.all).data.eleventyNavigation.key;
const subpages = eleventyNavigation(collections.all, currentKey);
</script>
<dl webc:if="subpages.length > 0">
<x webc:for="page of subpages" webc:nokeep>
<dt><a :href="url(page.url)" @html="md(page.data.title)"></a></dt>
<dd><p @html="md(page.data.description)"></p></dt>
</x>
</dl>The eleventyNavigation front matter data entry is shadowed by the eleventyNavigation filter, therefore the current page is retrieved from the collection to gain access to the front matter data. In order to render the dt element together with the dd element for each subpage, they have to be enclosed by an arbitrary placeholder element that holds the webc:for attribute.
The subpages-index element can be added to a layout or template:
<subpages-index></subpages-index>