Welcome
This guide is written for program participants who will author interactive visual narratives on the Plant Humanities Lab platform. By the end of it you will be able to:
- Edit pages directly in your browser and see your changes within seconds
- Write a plant narrative using only Markdown
- Add interactive images, side-by-side comparisons, maps, videos, and timelines
- Create those visuals from links in your own writing
- Submit a finished narrative for review and publication
No prior experience with GitHub, Jekyll, or Markdown is assumed. Read straight through the first time, then come back to individual sections as a reference while you are writing.
Part 1 — What You Are Doing
What Is StoryKit?
StoryKit is the name used on this site for a simplified version of Juncture, a visual narrative authoring and display framework. Juncture grew out of a 2018 digital humanities collaboration between JSTOR Labs and Dumbarton Oaks, with one straightforward goal:
Enable students and scholars to create interactive visual narratives using Markdown — without requiring coding skills.
Juncture was created to make it easier to build web-based visual narratives that combine prose with rich visual and interactive content. StoryKit keeps that same core idea but in a simpler form tailored for this site, built directly on Jekyll instead of relying on heavy custom infrastructure.
For authors, the important point is that StoryKit lets you write mostly in regular Markdown and add special instructions wherever you want interactive viewers to appear: images, maps, videos, timelines, and more. You do not need to understand the technical details. You just need to know how to edit a Markdown file, add the appropriate viewer instructions, preview your work, and submit it for review.
What You Are Creating
A visual narrative is a web page that combines written text with interactive media. A StoryKit visual narrative may include:
- Text written in Markdown
- Plain images and high-resolution zoom-and-pan viewers
- Side-by-side before/after image comparisons
- Maps with markers, custom layers, and fly-to animations
- YouTube videos with timestamp jumping
- Embedded timelines and other interactive content
- Mathematical equations rendered by MathJax
- Flow charts, sequence diagrams, and other diagrams drawn with Mermaid
You write the narrative in a plain text file using Markdown, with StoryKit instructions added where interactive viewers should appear. When the site is published, GitHub Pages and Jekyll convert that file into a finished web page.
A Few Terms You Should Know
You don’t need to be a GitHub or Jekyll expert, but a few terms come up throughout this guide.
GitHub repository. The website is stored in a GitHub repository. Think of the repository as the project folder for the website. It contains every file needed to build the site, including all the visual narratives.
Branch. A Git concept for an independent copy of a repository. The repository has a main branch from which the live site is built; only designated administrators can change main directly. When you create a branch, you get your own copy of main to work in. You can create and edit files, preview your work, and revise freely without affecting the live site. Your changes stay on your branch until an administrator reviews and merges them into main.
Commit. GitHub’s version of a save. When you commit, you save your changes to your branch. Each commit can include a short comment (“commit message”) describing what changed, such as Add introduction section or Fix typo in caption.
Jekyll. The tool that turns the source files into finished web pages. You will never run Jekyll yourself. GitHub Pages runs Jekyll automatically when the site is published, and the preview tool imitates the same process so you can check your work in advance.
Markdown. A simple way to write formatted text using plain text. Headings, lists, links, and emphasis all have lightweight equivalents in Markdown that are much easier to type than HTML.
StoryKit viewer. An interactive element you can insert into a visual narrative: an image viewer, a map, a YouTube video, and so on. Viewers are added with Liquid include tags. Liquid is the templating language used by Jekyll; an include tag is a short instruction that tells Jekyll to insert a pre-built component at that point in the page. For a StoryKit viewer the tag looks like {% include embed/image.html src="..." %}. You supply the attribute values, and Jekyll handles the rest.
Preview tool. A small utility that lets you see how your visual narrative will look on the live site, without waiting for GitHub Pages to rebuild. It renders the page the same way the live site does.
Pull request. How you ask for your completed changes to be reviewed and possibly published. When your narrative is ready, you open a pull request from your working branch into main. An administrator reviews the changes and decides whether to merge them.
Part 2 — Getting Started
Before You Begin
Before you begin authoring, you need:
- A GitHub account
- Your GitHub username added to the plant-humanities/sandbox repository with permission to create branches and edit files
The repository you will work in is plant-humanities/sandbox. A program administrator will add your GitHub username to it. If you can view the repository in GitHub but you don’t see a pencil icon next to files, or you can’t create a branch, your account hasn’t been added yet. Contact the administrator.
Creating a GitHub Account
GitHub is a free service. To create an account:
- Go to https://github.com and click Sign up.
- Use an email address you can check. School or work email works fine.
- Pick a username. Your username will appear in URLs and in commit history, so choose something you don’t mind being public. Many people use a variant of their name.
- Verify your email through the confirmation message GitHub sends.
Pick your username carefully. Changing it later is possible but breaks links to your work. A short, professional-looking username serves you well past this program.
Once your account is active, share your username with the program administrator so it can be added to the repository.
Working on Your Own Branch
Once you have access to the plant-humanities/sandbox repository, start by creating a branch for your work.
- Open github.com/plant-humanities/sandbox. Near the top-left of the file list you will see the branch selector, a small button labelled with the current branch name (usually main) and a downward arrow.
- Click the branch selector. In the box that appears, type a branch name. Use lower-case letters and hyphens, for example
mango-narrative,mary-map-updates, orteam-rose-draft. Pick something that briefly describes your work. - Click Create branch:
<your-name>frommain.
You are now on your own branch. Any edits you make from this point on affect only this branch until you ask for them to be merged into main.
flowchart LR
A[Edit on your branch] --> B[Commit]
B --> C{Looks right?}
C -- "Not yet" --> A
C -- "Yes" --> D[Open Pull Request]
D --> E[Administrator reviews]
E --> F[Merged into main]
F --> G[Live site rebuilds]
Why work on a branch? While you experiment on your branch, the published version of the site keeps rendering from
main. Nothing you do on a branch is visible to the public until an administrator merges it in.
Throughout the rest of the guide, always check that the branch selector shows your branch (not main) before editing. The branch selector is visible at the top of the file list any time you are browsing the repository; check it every time you return to GitHub to continue working.
Editing a File on GitHub
Most of your authoring time will be spent editing files you have already created. To edit any file in the repository:
- Confirm the branch selector shows your branch.
- Navigate to the file. For example, click into the
_postsfolder and then click your narrative’s.mdfilename. - GitHub shows the rendered preview of the file. To edit it, click the pencil icon (✏) in the upper-right area of the file view, near the Raw and Download buttons.
- The editor opens. Make your changes.
- When finished, scroll down to the Commit changes section at the bottom of the page.
- Optionally type a short description of what you changed (e.g. Add map viewer for section 2).
- Leave “Commit directly to the
<your-branch>branch” selected, then click Commit changes.
Your changes are saved to your branch and are immediately available to preview.
The GitHub editor has a Preview tab (at the top of the editing area) that shows basic Markdown formatting: headings, bold, italics, and lists. It is handy for checking paragraph structure. However, it does not render StoryKit viewers; those show as raw code in GitHub's preview. Use the bookmarklet preview tool to see viewers rendered correctly.
Using the Preview Tool
When you commit a change on GitHub, the live site does not update immediately. GitHub Pages must rebuild the entire site, which takes one to five minutes. During that wait you cannot see your edits.
The StoryKit preview tool sidesteps that wait by rendering a single file directly from your branch, usually in under five seconds.
One-time setup
You install the preview tool by dragging a bookmarklet into your browser’s bookmarks bar. You only do this once per browser.
- Make sure your bookmarks bar is visible:
- Chrome / Edge: ⌘⇧B on macOS, Ctrl+Shift+B on Windows
- Firefox: View menu → Toolbars → Bookmarks Toolbar
- Safari: View menu → Show Favorites Bar
- Drag the button below into your bookmarks bar. Do not click it — drag it.
Drag the button above to your bookmarks bar
- Confirm that a new bookmark labelled Preview on GitHub now appears in your bookmarks bar.
The bookmarklet reads the current GitHub page address and builds the preview URL for you, so you don’t have to construct it by hand.
Day-to-day use
Once the bookmarklet is installed:
- Open github.com/plant-humanities/sandbox and navigate to your
.mdfile in the_postsfolder. - Click Preview on GitHub in your bookmarks bar.
- A new tab opens with the file rendered the same way the live site would render it.
Work with two browser windows side by side. Keep GitHub open in one window and the preview in the other. After each commit, switch to the preview window and reload. This edit-commit-reload cycle makes it easy to catch problems before they pile up.
If the preview fails to open, check that you launched the bookmarklet while looking at a
.mdfile (not a folder or another file type). The bookmarklet only works on.mdpages inside a repository.
Part 3 — Markdown Basics
The text of every visual narrative is written in Markdown, a plain-text format for writing styled documents. You will never need to write HTML by hand. Markdown is small enough to learn in an afternoon; the rest of this part covers everything you need for a polished article.
For a comprehensive Markdown reference, see Markdown Guide. If you want to experiment with Markdown before using it in a narrative, web-based playgrounds such as Dillinger let you type Markdown on one side and see the rendered result instantly on the other, with no setup required.
A Markdown file has two parts:
- Front matter: a block at the very top, between two
---lines, that tells the site what the post is and how to display it. - Body: everything below the front matter. This is your narrative.
A minimal narrative looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
---
title: The Mango Tree
description: A short cultural history of the mango.
author: Your Name
date: 2026-06-10
categories: ["Tropical Crops"]
tags: [mango, tropical-fruits]
published: false
featured: false
media_subpath: /assets/posts/mango
image:
path: mango_header.jpg
alt: A mango tree in full fruit
---
The mango tree...
Each front matter field plays a role:
| Field | What it does |
|---|---|
title | The page heading and browser tab title |
description | A one-paragraph summary shown in search results and on article cards |
author | Your name as it should appear in the by-line |
date | Publication date; must match the date prefix in the file name |
categories | One or two broad subject categories used to group articles on the site — e.g. ["Tropical Crops"] or ["Trade & Empire", "Colonial Commodity"] |
tags | Any number of keyword tags for filtering and search — e.g. [mango, tropical-fruits] |
published | Set to false while drafting; change to true when you submit the pull request |
featured | Set to true to highlight the article on the home page; leave false unless asked by an administrator |
storykit | StoryKit extensions are enabled by default — you do not need this field. Add storykit: false only if you want to disable all viewers on a specific page |
media_subpath | The folder where your uploaded images live. Must match the folder name in assets/posts/ exactly (see §3.1) |
image.path | The header image shown on the article card and at the top of the page. Use a wc: shorthand for a Wikimedia Commons file (e.g. wc:Mangifera_indica.jpg) or a local filename. Aim for an image that looks good at roughly 16:9 landscape proportions |
image.alt | A brief text description of the header image, used for screen readers and accessibility |
StoryKit extensions are enabled by default — you do not need a
storykit:line in your front matter. The only time you would add it isstorykit: falseto explicitly disable all viewers on a specific page.
The file _posts/.template.md in the repository is a starter you can copy when creating a new narrative.
3.1 Creating a New Narrative File
The main file for a visual narrative is a Markdown file stored in the _posts directory. To create a new one:
- In the plant-humanities/sandbox repository (on your branch), navigate to the
_postsfolder. - Click
.template.mdto open it, then click the Raw button in the upper-right area of the file view. This shows the plain text of the template with no rendering applied. Select all (⌘A / Ctrl+A) and copy. - Go back to the
_postsfolder and click Add file → Create new file. Name the new file following this pattern:
1
yyyy-mm-dd-narrative-name.md
For example:
1
2026-06-10-mango.md
Use hyphens instead of spaces in the narrative name. The date at the beginning is important because Jekyll uses it to organise posts.
- Paste the template contents into the editor area, then fill in the front matter fields.
- Make sure
published: falseis set while you are still drafting. - Commit changes to save it to your branch.
Name the file thoughtfully. The narrative name portion of the filename (e.g.
mango) becomes part of the page's permanent URL. Changing it later is possible but breaks any saved or shared links. Keep it short, lower-case, and descriptive.
3.2 Headers and Section Titles
A header is a line of text marked as a heading. The number of # characters at the start of the line sets its level.
1
2
3
## Major section
### Sub-section
#### Sub-sub-section
##is the title of a major section in your narrative.###is a sub-section within that.####and below nest further.
Your narrative’s title: in the front matter is rendered as the page’s top-level (#) heading, so do not use # anywhere in the body of your narrative. Start with ## for your first section. The auto-generated table of contents is built from ## and deeper headings, assuming this structure.
A blank line is required before and after every header. Without the blank line above it, the header is rendered as part of the previous paragraph.
The site automatically builds a table of contents from your headers when toc: true is set in the front matter (it is on by default).
3.3 Italics, Bold, and Other Emphasis
Wrap text in asterisks or underscores to emphasise it.
1
2
3
4
*italic* or _italic_
**bold** or __bold__
***bold italic*** or ___bold italic___
~~strikethrough~~
Use italics for the scientific name of a plant (Mangifera indica), for the title of a book or journal, and for foreign-language words on first use. Use bold sparingly; it loses its force quickly if overused.
3.4 Popovers (Entity Information Boxes)
A popover is a small information panel that appears when a reader clicks a linked term in your text. Instead of sending the reader off to Wikipedia and breaking their reading flow, the relevant facts appear in place.
Popovers are powered by Wikidata, a free, structured database maintained by the Wikimedia Foundation. Almost every notable person, place, plant, organisation, and concept has a Wikidata entry, and each entry has a short identifier that starts with Q.
Finding a Wikidata identifier
- Search Wikipedia for the subject.
- On the Wikipedia article, look in the left-hand sidebar for Wikidata item.
- The page that opens shows the identifier at the top, for example Q156928 for Viburnum opulus.
Writing the link
The link in Markdown is identical to a normal link, except the URL is just the Q-identifier.
1
The work of [Charles Darwin](Q1035) shaped modern biology.
When the reader clicks Charles Darwin, a popover opens with his portrait, dates, summary, and a link to Wikipedia.
A worked example: the flowering shrub Viburnum opulus is native to Europe, north Africa, and northern Asia. It was studied by Carl Linnaeus and given the common name guelder rose after the Gelderland region of the Netherlands.
Use popovers selectively. One per concept is plenty; linking the first meaningful mention of a person, place, or species is usually enough.
3.5 URLs (Links)
A normal link looks the same as a popover link, except the URL points to a website.
1
[Plant Humanities Lab](https://lab.plant-humanities.org)
You can also drop a raw URL into your text by wrapping it in angle brackets:
1
Visit <https://lab.plant-humanities.org> to see published narratives.
For links to a place inside the same article, use the auto-generated anchor for the header you want to jump to. Each header gets an anchor made by lower-casing the text and replacing spaces with hyphens.
1
See the [Map Viewer](#43-map-viewer) section below.
3.6 Footnotes
Footnotes let you cite sources without cluttering the prose. Kramdown (the Markdown processor Jekyll uses) supports them with a two-part syntax.
- In the body, place a marker where the footnote should appear.
- Anywhere later in the file (usually at the bottom), write the definition.
1
2
3
4
5
6
7
The guelder rose plays a prominent role in Ukrainian folk song.[^1]
Charred remains have been found at Mesolithic settlements
on the Baltic coast.[^baltic]
[^1]: Smith, *Folk Songs of the Dnipro*, 142.
[^baltic]: Bjerck, "Coastal Mesolithic Diet", *Antiquity* 78 (2004), 287–294.
A few things to know:
- The marker can be a number (
[^1]), a word ([^baltic]), or anything that does not contain spaces. Numbers are renumbered automatically in the order they appear, so you don’t have to keep them in sequence. - The definition lines must each start at the left margin.
- A blank line is required before the first definition.
- Clicking a footnote in the rendered article scrolls the reader to the definition and adds a back-arrow that returns them.
Part 4 — The Content Viewers
The content viewers are what set the Plant Humanities Lab apart from a standard blog. They are interactive components — images you can zoom into, maps you can pan around, before-and-after sliders, embedded videos — each added to your narrative with a single line of code.
The line uses Jekyll’s Liquid include syntax. It looks like this:
1
2
3
4
{% include embed/<viewer-name>.html
attribute1="value"
attribute2="value"
%}
You do not need to understand Liquid in detail. Copy an example from this guide, change the attribute values to your own, and you are done.
If you copy a viewer tag from this guide's raw source on GitHub, be aware that the code examples are wrapped in Jekyll protection markup to prevent this guide page from being affected by its own examples. Those wrapper lines are not part of the viewer syntax. Copy only the
{% include embed/... %}lines themselves — nothing before or after them.
Two rules apply to every viewer:
- Attribute values must be in straight double quotes (
"value"), not curly quotes ("value"). - If you want to drive the viewer from a link in your text (for example, a “zoom in here” link), you must give the viewer an
id.
Watch out for curly quotes. Typing a viewer tag directly in GitHub's editor produces straight quotes automatically. But if you draft the tag in a word processor (Word, Google Docs, Apple Pages) and paste it in, the quote characters are often silently converted to typographic curly quotes (
"and"). The viewer will fail to render with no obvious error message. If a viewer shows as a placeholder, check its quote characters first.
4.1 Image Viewer
The Image Viewer displays an image that looks like an ordinary photo. When the reader clicks it, a large, high-resolution version of the viewer opens with smooth zoom and pan. This is the right component for any image whose detail matters: herbarium specimens, archival photographs, botanical illustrations, paintings.
The viewer supports three source types:
- Wikimedia Commons: referenced with a
wc:shorthand; caption, attribution, and license are fetched automatically. - Any URL: a direct link to any publicly accessible image, including IIIF-served images and museum collection pages.
- Locally hosted: an image file uploaded into the repository.
Using a Wikimedia Commons image
Wikimedia Commons is the free media library that powers Wikipedia, and it is the preferred source for narrative images. The Image Viewer has built-in support for Commons: it fetches the caption, attribution, and license information automatically, so you don’t need to enter them by hand.
To use a Commons image:
- Find the image on Commons.
- Copy the file name. It appears at the top of the file page, for example
File:Monument Valley, Utah, USA.jpg. - In your Markdown, reference it with the shorthand
wc:File_Name.jpg(replace spaces with underscores; do not include the leadingFile:).
1
2
3
{% include embed/image.html
src="wc:Monument_Valley,_Utah,_USA.jpg"
%}
Caption, photographer credit, and license text are fetched automatically. Most files on Commons are public domain or available under open licenses, but take a moment to check the file page for any specific requirements.
If you own the image, consider uploading it to Wikimedia Commons. Commons is a well-maintained, long-term hosting platform backed by the Wikimedia Foundation. Uploading there gives your image archival storage, support for detailed descriptive metadata, and a licensing framework you control. It also makes the image available to other researchers and educators under whatever terms you choose. Once it's on Commons, the Image Viewer handles attribution automatically, just like any other Commons image.
Using any URL-accessible image
The viewer can display any image that is publicly accessible via a URL: museum collection images, images hosted on institutional repositories, or images served via the IIIF standard.
Direct image URL:
1
2
3
4
5
{% include embed/image.html
src="https://example-museum.org/collections/images/specimen_12345.jpg"
caption="Herbarium specimen, collection of Example Museum"
attribution="© Example Museum, used with permission"
%}
IIIF manifest URL: many museums publish high-resolution images via IIIF. If a museum provides a manifest URL, pass it with the manifest attribute instead of src; the viewer loads the manifest and displays the image at full resolution with metadata drawn from it:
1
2
3
{% include embed/image.html
manifest="https://iiif.harvardartmuseums.org/manifests/object/299843"
%}
Use the attribution attribute to add or override the credit line when the automatic metadata from the source is incomplete.
Using a locally hosted image
A “local” image is one you have uploaded into the repository itself. Use this option when the image is not available from any public URL, for example a personal photograph or a scan obtained specifically for this narrative.
Before uploading an image locally, ask whether you could instead upload it to Wikimedia Commons. If you own the image and are willing to share it under an open licence, Commons is the better long-term home: it provides archival preservation, rich metadata, and automatic attribution handling that local hosting does not.
To upload and reference a local image:
- In the plant-humanities/sandbox repository on your branch, navigate to
assets/posts/. Click Add file → Create new file. In the filename field, type your folder name followed by
/and a placeholder filename, for examplemango/.gitkeep. Add a single space as the file content, then commit. This creates theassets/posts/mango/folder.GitHub cannot save an empty folder. You must create at least one file inside a new folder before GitHub will save it. The
.gitkeepplaceholder file above serves that purpose; you can delete it later once real image files are in the folder.- Navigate into
assets/posts/mango/and click Add file → Upload files to upload your image files. Commit the upload. Make sure the narrative’s front matter sets
media_subpathto that folder, and that the folder name andmedia_subpathvalue match exactly.1
media_subpath: /assets/posts/mango
In the include tag, use only the file name:
1 2 3 4
{% include embed/image.html src="mango_specimen.jpg" caption="Herbarium specimen, Mangifera indica, 1885" %}
Because media_subpath is set, the platform automatically resolves mango_specimen.jpg to /assets/posts/mango/mango_specimen.jpg. If the image fails to load, the most common cause is a mismatch between the folder name and the media_subpath value.
Useful optional attributes
| Attribute | What it does |
|---|---|
caption | Text shown below the image |
attribution | Override or supplement the credit line — important for URL and locally hosted images where automatic attribution is not available |
aspect | Sets the displayed shape — e.g. aspect="1.33" or aspect="1200/630" |
cover | Set to "true" to make the image fill its space dramatically |
region | Open the viewer zoomed into a particular area — see §4.5 for how to get this value |
rotate | Rotate the image — accepted values are "90", "180", or "270" |
seq | Select a specific image in a multi-image IIIF manifest. The first image is 1. For example, seq="3" displays the third image |
id | Required only if you want to target the viewer from a link |
4.2 Image Compare Viewer
The Image Compare Viewer places two images on top of one another with a vertical divider the reader can drag back and forth. It is the right component for before/after pairs: a historical photograph against a modern view, a herbarium specimen against a field photograph, a landscape painting against the present-day landscape.
Basic use
You need two images (either local files or Wikimedia Commons files) in the same folder, and you set the before and after attributes.
1
2
3
4
5
6
7
{% include embed/image-compare.html
before="Westgate_Towers_c1905.jpg"
after="Westgate_Towers_2021.jpg"
caption="Westgate Towers, Canterbury — c.1905 vs 2021"
aspect="1.5"
position="50"
%}
beforeis the image revealed as the divider is dragged left (usually the older image).afteris the image visible when the divider is fully to the right (usually the newer image).captionappears below the viewer.aspectsets the shape of the expanded dialog.1.5suits most landscapes;0.75suits portraits.positionsets the starting position of the divider, as a percentage from the left edge.50is centred;35puts it left of centre so the after image dominates initially.
When the reader clicks the preview in the page, an expanded view opens that fills the screen width.
Aligning the two images
Two photographs taken decades apart are almost never framed identically. To line them up, open the expanded viewer in the preview, double-click the comparison, and the alignment panel slides open below. It has two tabs — Before and After — each with three sliders:
| Slider | Effect |
|---|---|
| X | Shift the image left or right |
| Y | Shift the image up or down |
| Zoom | Scale the image in or out from its centre |
While the panel is open the top image is partially transparent, so misalignment shows up as a double-image. Adjust until the subject lines up, then click Copy tag. A complete, corrected {% include embed/image-compare.html ... %} tag is copied to your clipboard. Paste it into your Markdown, replacing the previous tag, and the alignment is preserved for every future reader.
4.3 Map Viewer
The Map Viewer adds an interactive map to your narrative. The reader can zoom and pan; you can place markers, add a historical map overlay, draw shapes from a GeoJSON file, and animate the map from links in your text.
A simple map
1
2
3
4
5
{% include embed/map.html
center="37.01056, -110.2425"
zoom="10"
caption="Monument Valley, Utah"
%}
centeris required. It can be a pair oflatitude, longitudecoordinates, or a Wikidata Q-identifier for a place (the map centres on the place’s coordinates).zoomis a number from 1 (world view) to about 20 (street level). Default is 8.captionappears below the map.
Use a Wikidata Q-id for
centerwhen your map is centred on a named place. For example,center="Q220"(Rome) is more readable and maintainable than raw coordinates, and the platform resolves it automatically. Look up the Q-id on Wikipedia using the same steps described in §3.4.
A map with a marker
1
2
3
4
5
6
{% include embed/map.html
center="37.01056, -110.2425"
zoom="10"
markers="37.01056, -110.2425~Monument Valley"
caption="Monument Valley, Utah"
%}
Markers are written as latitude, longitude~Label. To add several markers, separate them with a pipe character |:
1
markers="37.01056, -110.2425~Monument Valley|36.0544, -112.1401~Grand Canyon"
You can also use a Wikidata Q-identifier in place of coordinates for a marker; the map resolves the location automatically. For example: markers="Q220~Rome".
Other useful attributes
| Attribute | What it does |
|---|---|
basemap | Choose a different map style — see the table below |
geojson | Path or URL of a GeoJSON file to draw on the map — useful for distribution ranges or trade routes |
allmaps | An Allmaps identifier for layering a historical map on top of the modern one |
id | Required if you want to drive the map from links in your text (see §4.5) |
Available basemaps
| Value | Description |
|---|---|
OpenStreetMap | Default. Standard street and place-name map |
Esri_WorldPhysical | Physical relief map — well suited to plant distribution ranges and historical trade routes |
Esri_WorldImagery | Satellite / aerial imagery |
CartoDB_Positron | Minimalist light-grey map — good when markers or GeoJSON overlays should stand out against a quiet background |
You can list multiple basemaps separated by | to offer a layer-switcher control in the viewer. For example: basemap="OpenStreetMap|Esri_WorldPhysical".
4.4 YouTube Viewer
The YouTube Viewer embeds a YouTube video as a clean preview. When the reader clicks the preview, an expanded player opens at full width. No video loads until the reader chooses to play, which keeps your page fast.
1
2
3
4
{% include embed/youtube.html
vid="H-B46URT4mg"
caption="Pollination in slow motion"
%}
The only required attribute is vid, the eleven-character video identifier. To find it, look at the YouTube URL: in https://www.youtube.com/watch?v=H-B46URT4mg, the vid is H-B46URT4mg.
Useful optional attributes:
| Attribute | What it does |
|---|---|
caption | Text shown below the video. If you omit it, the YouTube title is fetched. |
start | Time to start playing — in seconds ("90") or h:mm:ss form ("1:30"). |
end | Time to stop playing, same format as start. |
autoplay | Set to "true" to start playing as soon as the expanded view opens. |
id | Required for action links (see §4.5). |
Combine start and end to highlight a specific clip from a longer video.
4.5 Zoom-to and Fly-to Animations
This is what sets a Plant Humanities Lab visual narrative apart from a standard blog post: links in your prose can control the viewers on the page. A reader clicks a place name and the map flies there; they click a phrase and the image zooms in. The text and the visuals work together.
Three things have to be true for an action link to work:
- The viewer you want to control must have an
idattribute. - The link in your text must use that
idin a specific URL format. - The viewer must be on the same page as the link.
The URL format is always:
1
<viewer-id>/<action>/<arguments>
Zoom-to on an image
Use zoomto to make an image viewer zoom into a specific region. The argument is a percentage rectangle — pct:x,y,width,height — where each number is a percentage of the image’s dimensions from the top-left corner.
1
2
3
4
{% include embed/image.html
id="img1"
src="wc:Monument_Valley,_Utah,_USA.jpg"
%}
1
Look closely at [Merrick Butte](img1/zoomto/pct:67.68,34.23,23.22,27).
Look closely at Merrick Butte.
Click Merrick Butte in the live example to see the viewer open and zoom into that region, with the link text shown as a label.
Getting the region coordinates from the viewer
You don’t have to calculate the rectangle by hand. The high-resolution viewer can generate the coordinates for you:
- Click the image in the preview to open the full-screen high-resolution viewer.
- Zoom and pan to the area you want to highlight.
- Hold the mouse button and drag to draw a selection rectangle over the region of interest.
- The viewer displays a
pct:x,y,w,hstring for the selected area. Click Copy (or the string itself) to copy it to your clipboard. - Paste the string as the third segment of your action link:
[link text](img1/zoomto/pct:x,y,w,h).
Custom labels
By default the label shown on the zoomed region is the link text. To use different text, attach an attribute block:
1
[Watch the inner flowers](img3/zoomto/pct:23,40,15,18){: label="Fertile inner flowers" }
Fly-to on a map
Use flyto to fly a map smoothly to a new location and zoom level. The argument is latitude,longitude,zoom.
1
2
3
4
5
6
{% include embed/map.html
id="sites"
center="52.69,2.2"
zoom="3.8"
caption="Prehistoric sites with evidence of guelder rose"
%}
1
2
Charred seeds were found at [Tybrind Vig](sites/flyto/55.394211,9.810635,9),
a coastal Mesolithic settlement.
When the reader clicks Tybrind Vig, the map flies to that point and zooms to level 9.
Play-at on a YouTube viewer
Use playat to open a YouTube viewer at a specific timestamp. The argument is start or start,end.
1
[Watch the chorus](vid1/playat/42,75)
This opens the expanded video, seeks to 0:42, and stops at 1:15.
Action link reference
| Viewer | Action | Argument | Effect |
|---|---|---|---|
| Image | zoomto | pct:x,y,w,h | Open the viewer zoomed to a percentage region |
| Map | flyto | lat,lng,zoom | Animate the map to a new view |
| YouTube | playat | start or start,end | Open the expanded video at a time |
Action links only work when the viewer is on the same page. If clicking a link does nothing, check that the
idin the link exactly matches theidon the viewer's include tag.
4.6 The General Iframe (and Timeline JS)
For content that isn’t covered by the dedicated viewers, the general iframe include lets you embed any external interactive page. An iframe is simply a web page displayed inside another web page; all you need to provide is its URL.
1
2
3
4
5
{% include embed/iframe.html
src="https://archive.org/embed/vignettesfromnat00alleuoft/page/93"
caption="Vignettes from Nature, by Grant Allen, 1881"
aspect="0.65"
%}
Attributes:
| Attribute | What it does |
|---|---|
src | Required. The URL of the page to embed. |
caption | Text shown below the embed. |
aspect | Width-to-height ratio. Use 0.65–0.75 for portrait pages, 1.5–1.78 for video-style content. |
width, height | Set fixed pixel dimensions if you need them. Most of the time you don’t. |
id | Identifier, in case you want to target the embed from a link. |
Embedding a Timeline JS timeline
Timeline JS is a free tool from Northwestern University’s Knight Lab that turns a Google Sheet into an interactive timeline. It’s a natural fit for plant histories that span centuries.
The workflow is:
- Open the Timeline JS template. Visit https://timeline.knightlab.com and click Make a Timeline. Follow the Get the Spreadsheet Template link to make your own copy.
- Fill in your events. Each row of the sheet is one moment on the timeline: a date, a headline, a paragraph of text, and optionally a media URL (image, YouTube link, Wikipedia page).
- Publish the sheet. In Google Sheets, choose File → Share → Publish to web and accept the defaults.
- Generate the embed URL. Back on the Timeline JS site, paste the URL of your published sheet into the box. The site gives you a Preview URL, something like
https://cdn.knightlab.com/libs/timeline3/latest/embed/index.html?source=<your-sheet-id>. Embed it in your narrative:
1 2 3 4 5
{% include embed/iframe.html src="https://cdn.knightlab.com/libs/timeline3/latest/embed/index.html?source=YOUR_SHEET_ID" caption="A timeline of the mango" aspect="1.6" %}
That’s all. To update the timeline later, just edit the Google Sheet and your narrative will pick up the new version automatically the next time the page loads.
The same pattern works for any external page that allows embedding: Internet Archive book viewers, museum collection pages, Sketchfab 3-D models, charts from Datawrapper or Flourish, and so on. If a service provides an embed URL, the iframe include is what you need.
4.7 Mermaid Diagrams
Mermaid is a text-based diagramming language built into the platform. It lets you write simple descriptions of flow charts, sequence diagrams, Gantt charts, and other diagram types, which are rendered as clean vector graphics in the finished narrative.
Enabling Mermaid
Add mermaid: true to your narrative’s front matter:
1
mermaid: true
Writing a diagram
Wrap Mermaid code in a fenced code block labelled mermaid:
1
2
3
4
5
6
7
8
```mermaid
flowchart LR
A[Collect sources] --> B[Draft narrative]
B --> C[Add viewers]
C --> D[Preview]
D -- Revise --> B
D -- Done --> E[Submit pull request]
```
Result:
flowchart LR
A[Collect sources] --> B[Draft narrative]
B --> C[Add viewers]
C --> D[Preview]
D -- Revise --> B
D -- Done --> E[Submit pull request]
The Mermaid documentation lists all supported diagram types and their syntax. The most useful for humanities narratives are flowchart (process and argument diagrams), sequenceDiagram (interactions over time), and gantt (timelines of overlapping activities).
4.8 Mathematical Equations (MathJax)
MathJax renders LaTeX-style mathematical notation. It is useful for narratives that discuss quantitative methods, statistical relationships, or any content where a properly typeset equation communicates more clearly than prose.
Enabling MathJax
Add math: true to your narrative’s front matter:
1
math: true
Writing equations
Use $$ as the delimiter. The placement of blank lines determines whether the equation is displayed as a block or inline.
Block equation (its own centred line); blank lines are required before and after the $$ delimiters:
1
2
3
$$
\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
$$
Inline equation (flows within a sentence); no blank lines:
1
The result follows from $$ E = mc^2 $$ directly.
Inline equation in a list item; escape the first $:
1
- \$$ \sum_{n=1}^\infty \frac{1}{n^2} = \frac{\pi^2}{6} $$
MathJax accepts standard LaTeX math-mode commands. If you are new to LaTeX notation, the LaTeX Mathematics Wikibook is a practical reference.
Part 5 — Publishing Your Narrative
When Your Narrative Is Ready
When your visual narrative looks the way you want it to in the preview tool, you’re ready to submit it for review. Set published: true in the front matter, commit, and then open a pull request.
A pull request says, in effect:
I have finished these changes on my branch. Please review them and consider adding them to the live site.
To open a pull request:
- In the plant-humanities/sandbox repository on GitHub, click the Pull requests tab.
- Click New pull request.
- Set the base branch to
mainand the compare branch to yours. - Click Create pull request.
- Write a brief description of what your narrative is about. (The commit messages on your branch are visible to the reviewer as well.)
The pull request does not automatically publish your narrative. It gives an administrator a chance to review the work first.
Make sure the preview looks right before opening the pull request. The administrator will see your narrative as it is when the request is opened. You can still commit fixes after opening it (the pull request updates automatically), but it is cleaner to resolve everything first.
What an Administrator Does
An administrator reviews the pull request and may:
- Approve the changes as-is
- Ask for revisions
- Make small fixes themselves
- Merge the changes into
main
When the pull request is merged, GitHub Pages rebuilds the website and your visual narrative becomes part of the live site, usually within one to five minutes.
Why This Workflow Matters
This workflow protects the live website while still letting authors work independently. It means:
- Authors can safely draft and revise content
- The live website isn’t changed until work has been reviewed
- The preview tool lets authors see a realistic version of the final page
- Administrators retain control over what gets published
- Mistakes can be caught before they appear on the public site
The key idea is straightforward: authors work in branches, the live site is published from main, and pull requests are how finished work gets reviewed and published.
Part 6 — Practical Tips
Save Small Changes Often
It’s better to make several small commits than one very large commit. Small changes are easier to review, easier to undo if something goes wrong, and easier to describe in a commit message.
Preview After Every Viewer You Add
Don’t wait until the whole narrative is finished before using the preview tool. Commit and preview after adding each new StoryKit viewer. That way, if something breaks you know exactly which change caused it. Waiting until the end to preview makes problems much harder to trace.
Use Clear File Names
Use file names that are short, descriptive, and consistent with the site’s existing naming pattern. Avoid spaces; use hyphens instead.
Good: 2026-05-12-history-of-the-garden.md
Avoid: My New Essay Final Version.md
Keep Captions and Credits Accurate
Images and other media are often central to a visual narrative. Double-check that captions, credits, and source information are correct before submitting, especially when using locally uploaded images that don’t carry automatic Wikimedia attribution.
Ask for Help Before Publishing
If something doesn’t look right in the preview, ask for help before opening the pull request. Most problems are easy to fix once identified (a missing id, a mismatched media_subpath, a stray curly quote), but they’re hard to see when you’ve been looking at the same draft for hours.
Part 7 — Reference
Quick Reference
A condensed cheat sheet for everything in Part 4.
| You want to … | Use … |
|---|---|
| Show a high-resolution image that can be zoomed | {% include embed/image.html src="..." %} |
| Show a before/after pair with a draggable divider | {% include embed/image-compare.html before="..." after="..." %} |
| Show an interactive map | {% include embed/map.html center="..." %} |
| Embed a YouTube video | {% include embed/youtube.html vid="..." %} |
| Embed anything else (e.g. Timeline JS) | {% include embed/iframe.html src="..." %} |
| Add a Mermaid diagram | Fenced code block labelled mermaid (requires mermaid: true in front matter) |
| Add a mathematical equation | $$ LaTeX $$ — block (with blank lines) or inline (no blank lines) — requires math: true in front matter |
| Add a Wikidata popover to a phrase | [phrase](Q12345) |
| Add a footnote | …claim.[^1] and later [^1]: source |
| Zoom an image to a region from a link | [text](imageId/zoomto/pct:x,y,w,h) |
| Fly a map to a location from a link | [text](mapId/flyto/lat,lng,zoom) |
| Jump a video to a timestamp from a link | [text](videoId/playat/start,end) |
Pre-Submission Checklist
Before opening a pull request, verify:
published: trueis in the narrative’s front matter- The
media_subpathmatches the folder where you uploaded images - Every StoryKit viewer renders correctly in the preview when you scroll the whole article
- All Wikidata Q-identifiers in popover links point to the right entity
- All footnotes resolve to a definition at the bottom of the file
- Captions and attribution on local images are correct
- The branch contains only commits related to your narrative, with nothing accidental included
- The file name follows the
yyyy-mm-dd-narrative-name.mdpattern
Troubleshooting
If something isn’t behaving the way you expect, work through this list in order.
- A viewer is showing as a broken image or a placeholder. Check that the narrative’s front matter does not contain
storykit: false, which disables all viewers. - A local image isn’t loading. Check that
media_subpathin the front matter exactly matches the folder name inassets/posts/. Capitalisation and dashes matter. - An action link does nothing when clicked. Check that the viewer has an
idattribute and that the link’s URL begins with exactly thatid. - Quotes around an attribute value cause errors. Use straight double quotes
"...", not curly ones"…". Curly quotes often appear when text is pasted from word processors. - An image is not rotating. Use
rotate="90"(or"180","270"). Some older narratives in the repository userotation=, which is not supported and has no effect; rename it torotate=. - Footnotes aren’t rendering. Make sure there is a blank line before the first
[^x]:definition. - Your changes aren’t showing up on the public site. Confirm that
published: trueis in the front matter, the pull request has been merged intomain, and that one to five minutes have passed for the rebuild. - The preview tool isn’t opening. Make sure you launched the bookmarklet while looking at a
.mdfile on GitHub, not a folder.
Where to Go from Here
- Read published narratives to see these techniques in action. In the plant-humanities/sandbox repository, open
_posts/2025-08-09-guelder-rose.md(rich use offlytoandzoomto) and_posts/2024-07-11-soybean.md(multiple maps and embedded archival pages). To read the raw source of either file, open it in GitHub and click Raw. - Browse the Admin docs on the live site for deeper reference on each viewer.
- When your narrative is ready, open a pull request and an administrator will review it.
Good writing.
