Templates read the build through variables whose names start with $. Layouts, .hbs content, and output files get all of them. Partials get them for the page that renders them. Data modules get $site, $pages, $section, $tags, $data, and $utils.
The examples on this page show what each variable holds while bongo renders this post, on a site whose $site.url is https://example.com/:
---
title: Hello, world
summary: My first post.
date: 2024-05-01
tags: [js, css]
draft: false
---
Static sites with a good beat.
## Why bongo
It is fast.
### Setup
Run it.The site also has content/index.md, content/about.md, content/blog/index.md, content/blog/second.md, and data/site.yaml.
$page
An object with data about the current page. For the example content/blog/hello.md file, the $page object holds:
{
path: '/blog/hello/',
url: 'https://example.com/blog/hello/',
title: 'Hello, world',
summary: 'My first post.',
section: 'blog',
tags: ['js', 'css'],
params: {
title: 'Hello, world',
summary: 'My first post.',
date: '2024-05-01',
tags: ['js', 'css'],
draft: false,
},
headings: [
{ level: 2, id: 'why-bongo', text: 'Why bongo', html: 'Why bongo' },
{ level: 3, id: 'setup', text: 'Setup', html: 'Setup' },
],
draft: false,
content: '<p>Static sites with a good beat.</p>\n<h2 id="why-bongo">…',
}| Field | What it holds |
|---|---|
path |
The URL path of the page. On a site under a subpath, it starts with that subpath. See Page URLs. |
url |
The absolute URL of the page. |
title |
The title frontmatter, as text. '' when the page has none. |
summary |
The summary frontmatter, as text. '' when the page has none. |
section |
The folder of the content file inside content/, such as blog or docs/guides. '' for a file at the root of content/. See Sections. |
tags |
The tags frontmatter, as a list. The frontmatter can be a list or a comma-separated string. See Tags. |
params |
All the frontmatter, with typed values. See Frontmatter. |
headings |
The headings that the page's loader reports, each with its level, id, plain text, and inner html. @bongo/markdown reports every Markdown heading. .html and .hbs content has none. |
draft |
true when the page is a draft: it has draft: true, or a date after the build started, unless it has draft: false. Only a build with drafts, such as bongo dev, has a draft. |
content |
The body of the page, as HTML. Print it with {{{ $page.content }}}. While the page's own .hbs body compiles, content is empty. |
A table of contents from headings:
<ol>
{{#each $page.headings.filter(h => h.level === 2) as h}}
<li><a href="#{{ h.id }}">{{{ h.html }}}</a></li>
{{/each}}
</ol>$pages
Every page of the build, sorted by path. Each entry has the fields of $page, except content. Output files and data modules are not in it, and neither are drafts, unless the build has them.
[
{
path: '/',
url: 'https://example.com/',
title: 'Home',
summary: '',
section: '',
tags: [],
params: { title: 'Home' },
headings: [{ level: 1, id: 'home', text: 'Home', html: 'Home' }],
draft: false,
},
{ path: '/about/', title: 'About', section: '', … },
{ path: '/blog/', title: 'Blog', section: 'blog', … },
{ path: '/blog/hello/', title: 'Hello, world', section: 'blog', … },
{ path: '/blog/second/', title: 'Second post', section: 'blog', … },
]In output files and data modules, each entry also has alternates: the <bongo:alternate> elements of the page, by type, such as { 'text/markdown': '/about.md' }. Pages render first, so these files see the elements of every page. See Alternates.
$section
The pages in the same section as the current page, sorted by path, with the same fields as $pages. The section includes its index page and the current page. For content/blog/hello.md:
[
{ path: '/blog/', title: 'Blog', section: 'blog', … },
{ path: '/blog/hello/', title: 'Hello, world', section: 'blog', … },
{ path: '/blog/second/', title: 'Second post', section: 'blog', … },
]A page at the root of content/ gets the other root pages: / and /about/ here. The posts of a blog, newest first:
{{#var posts = $section.filter(post => post.params.date)}}
{{#var newest = posts.toSorted((a, b) => b.params.date > a.params.date ? 1 : -1)}}
{{#each newest as post}}
<a href="{{ post.path }}">{{ post.title }}</a>
{{/each}}$tags
One entry for each tag, with the pages that have it. The tags come in the order in which they first appear in $pages. The pages of each tag are sorted by path.
[
{
tag: 'js',
pages: [{ path: '/blog/hello/', title: 'Hello, world', … }],
},
{
tag: 'css',
pages: [
{ path: '/blog/hello/', title: 'Hello, world', … },
{ path: '/blog/second/', title: 'Second post', … },
],
},
]$site
The $site field of the config. description is '' and menu is {} when the config does not set them.
{
url: 'https://example.com/',
lang: 'en',
title: 'My Site',
description: 'A site built with bongo.',
menu: {},
}$data
The files in data/, keyed by their paths without the extension. See Data.
author: Luke
links: [github, npm]{ site: { author: 'Luke', links: ['github', 'npm'] } }$utils
The helper functions, such as {{ $utils.date.format($page.params.date, { dateStyle: 'long' }) }}. See Utilities.
$assets
An object with two methods for the files of assets/.
load(filename, encoding?) reads a file from assets/ and returns a promise of its text, or of a Buffer when you give no encoding. A missing file fails the build. Inline an icon:
{{{ await $assets.load('icons/star.svg', 'utf8') }}}render(template, output?, options?) draws a partial as an image, with the values of the current page, and returns a promise of the URL path of the image. Make a social card for each page:
{{#var card = await $assets.render('og/card')}}
<meta property="og:image" content="{{ $utils.url.abs(card) }}"/>See Dynamic images and Open Graph images.
params
In .hbs content and output files, params is a short name for $page.params, such as {{ params.date }}.