Wiki Home
About
Planned Features
Image galleryAudio EmbeddingBlockquote styling- /uses
BlogrollNot by AI badge on posts- Résumé
Documentation
Custom Filters
abbr- Returns an<abbr>tag with a definition in thetitleattribute:{{ "USD" | abbr("United States Dollars") | safe }}returns<abbr title="United States Dollars">USD</abbr>.- Use
safefilter so that HTML is unescaped.
htmlDateStringmarkdownify- parses string as markdownniceDate- returns a nice string from dates, E.G.,2026-01-01returns1st of January, 2026removeHash- removes the trailing "#" from stringsremoveMostRecent- removes most recent item from an array
Frontmatter
structuredData: none- Disables "BlogPosting" schema JSON, Open Graph, and Twitter Card metadata, which is by default on for all templates with atitle.excludeProfilesFromHead: true- disables printing of indieweb profile links in page head.
Metadata
Features configured in metadata.js:
/me
Links at /me are configured in metadata.js like so:
socialLinks: [
{
customAttribute: `rel="me"`, /* optional */
excludeFromHead: true, /* optional */
title: "My Blog",
linkURL: "https://nathanupchurch.com",
linkDisplay: "My Blog",
iconURL: "/img/logo.svg"
}
]
Any links added here will render on the /me page.
Webrings
Webrings configured in metadata.js will display in the footer of most pages beneath the copyright notice:
webrings: [
{
name: "Fediring",
ringURL: "https://fediring.net/",
previousURL: "https://fediring.net/previous?host=nathanupchurch.com",
nextURL: "https://fediring.net/next?host=nathanupchurch.com"
}
]
Mastodon Integration
Adding link to discuss on Mastodon
Simply add a toot ID to a post's frontmatter using the mastodon_id key in order to enable a link to discuss on Mastodon:
mastodon_id: "112409293978326719"
Other Special Features
Special or uncommon features of this blog that aren't configured in metadata.js.
Embed audio
Embed audio using the custom "audio" shortcode:
{% audio "Title'", "Artist", "audioFile.mp3", "coverImage.webp" %}
Image Galleries
Specify galleries in _/data/galleries.js.
Quizzes
Quizzes can be specified using markdown files in /content/quizzes. The structure should look like this:
---
title: ""
description: ""
date: 2025-02-04
imageURL: ""
imageAlt: ""
consequences:
- title: ""
points: 0
spiel: ""
image: ""
imageAlt: ""
questions:
- title: ""
image: ""
imageAlt: ""
imageCaption: ""
answers:
- name: ""
points: 0
---
This is a great quiz that I'm sure you'll have fun taking. Let me tell you all about it…
Settings
How to add a settings "plugin," like woo-mode, or weather:
- Create a user-facing form control element at
_includes/settings/controllers/myController.njk, for example:
<form class="siteSettingsToggle" id="birbController">
<input type="checkbox" id="birbToggle" {% if metadata.weatherOnByDefault %}checked{% endif %} />
<label for="birbToggle">Pet bird (Will refresh page when turned off)</label>
</form>
- Create the logic for your settings plugin at
_includes/mySetting.njk, for example:
<!-- Birb -->
<script>
const showBirb = () => {
script = document.createElement('script');
script.setAttribute("src", "https://cdn.jsdelivr.net/gh/IdreesInc/Pocket-Bird@main/dist/web/birb.embed.js");
document.body.appendChild(script);
};
const hideBirb = () => {
window.location.reload();
};
const noBirb = () => {
console.info("Settings: Not showing birb :[");
}
</script>
<!-- /Birb -->
You will need, at minimum, two functions: one to start the plugin, and one to end it. Four are possible:
- start the plugin when it is loaded on a page by default
- start the plugin when it is toggled on by the user
- stop the plugin when it is off by default and the user has not turned it on
- stop the plugin when the user toggles it off
- Add the configuration for your setting in
_includes/settings/settingsConfig.njk, for example:
const petBirbSettings = {
handleOnToggle: showBirb,
handleOnDefault: showBirb,
handleOffToggle: hideBirb,
handleOffDefault: noBirb,
settingToggle: "birbToggle", // ID of the input created to control the setting
preferenceName: "petBirb", // Name to be used in local storage to record the user's preference
defaultSetting: false, // Whether the plugin will run by default in absence of a user preference
forcedOn: false, // Whether the plugin will ignore user preference and run anyway if on by default
};
- In the same file, hand off the config object to
settingHandler()which will handle the starting, stopping, and local storage for your plugin:
settingHandler(petBirbSettings);
- Add your plugin include to
_includes/layouts/base.njk:
{% include "birb.njk" %}