Loops
The {{#each}} directive repeats a block of markup for every item in an array. You use it to generate menus, lists, cards — any repeated structure driven by data.
Generate a navigation menu
Instead of hard-coding every link in your header, extract page titles and hrefs from your Markdown files and loop over them.
Extract the data
LiteNode's extractMarkdownProperties method reads an array of parsed files (or a directory path) and returns an array of objects containing only the properties you ask for:
const titles = await app.extractMarkdownProperties("markdown", ["title", "href"])
This returns something like:
[
{ "title": "Installation", "href": "installation" },
{ "title": "Basic Usage", "href": "basic-usage" },
{ "title": "Middleware", "href": "middleware" }
]
Sort it
The files come back in filesystem order. Sort them however you need:
// Alphabetically
titles.sort((a, b) => (a.title < b.title ? -1 : 1))
// By an index field in frontmatter
titles.sort((a, b) => a.index - b.index)
Pass it to the template
Add titles to the data object in every route that uses the navigation:
res.render("layouts/index.html", {
title,
description,
html_content,
titles,
tutorialRoute: true,
})
Render it with #each
In your header component:
<nav>
<a href="/">Home</a>
{{#each titles}}
<a href="/tutorial/{{href}}">{{title}}</a>
{{/each}}
</nav>
LiteNode's STE also provides {{#each1}}, {{#each2}}... for nested loops when you need to iterate over arrays within arrays or arrays of objects.
Build a grouped menu
For a sidebar with category groups, use groupByMarkdownProperty to group files by a frontmatter field, then loop over groups and items together:
const grouped = await app.groupByMarkdownProperty(
"markdown",
["metadata.category", "metadata.catIndex", "metadata.subcategory", "metadata.subCatIndex", "href"],
"metadata.category",
)
const mainMenu = Object.entries(grouped)
.map(([key, value]) => ({
key,
value: [...value].sort((a, b) => a["metadata.subCatIndex"] - b["metadata.subCatIndex"]),
}))
.sort((a, b) => a.value[0]["metadata.catIndex"] - b.value[0]["metadata.catIndex"])
Then in the sidebar template:
{{#each mainMenu}}
<section>
<h3>{{key}}</h3>
<ul>
{{#each1 value}}
<li>
<a href="/tutorial/{{href}}">{{"metadata.subcategory"}}</a>
</li>
{{/each1}}
</ul>
</section>
{{/each}}
This pattern — extract, sort, loop — scales to any number of pages with no template changes.
