Bartholomew templates
In Bartholomew, layout is handled via templates. All templates are in the
templates/
directory.
Handlebars is a simple template language well-tuned to HTML. While the version of Handlebars used in Bartholomew is written in Rust, not JavaScript, it works almost identically.
A Simple Template
Here is a simple HTML template with Handlebars:
<!DOCTYPE html>
<html>
<head>
<title>{{page.head.title}}</title>
</head>
<body>
{{{page.body}}}
</body>
</html>
The above sets the HTML document’s title to whatever is in page.head.title
, and
then fills in the body
with the value of page.body
.
Let’s take a brief look at the page
object to understand what is happening here.
The page
Object
In JSON, the page
object looks like this:
{
head: {
title: "Some title",
description: "Some description",
template: "an optional template rather than using main.hbs"
extra: {
"key": "value",
"description": "whatever is in the [extra] section of your Markdown doc's header"
}
},
body: "<p>Some rendered Markdown content</p>",
published: true
}
To access a part, you simply use a dotted path notation. So to get the value of key
in
the extra
section, we use {{ page.head.extra.key }}
.
The site
Object
In addition to the page
object, there is also a site
object. site.pages
contains the head
section and content of every page in the site. site.pages
is only populated for templates included in index_site_pages
in site.toml
as described in the configuration section:
{
info: {
title: "site title"
about: "Site about information"
base_url: "http://localhost:3000"
extra: {
copyright: "site-wide copyring (this is not required, since it's in extra)"
}
},
pages: [
{...},
{...}
]
}
Note that the site.pages
array has access to every single document in the content
folder.
This part of the API may change in the future, as it does not scale terribly well.
The env
Object
The third top-level object is env
, which holds all of the environment data.
The env
object is a set of keys and values:
{
PREVIEW_MODE: "0"
...
}
You can dump the entire contents of env
using a template like this:
<ul>
{{#each env}}
<li><code>{{@key}}</code>: <code>"{{this}}"</code></li>
{{/each}}
</ul>
The request
Object
The fourth top-level object is request
, which holds all the details about
the HTTP request, the path of this resource, and other Spin information.
The request
object is a set of keys and values:
{
spin-full-url: "http://localhost:3000/test"
...
}
You can dump the entire contents of request
using a template like this:
<ul>
{{#each request}}
<li><code>{{@key}}</code>: <code>"{{this}}"</code></li>
{{/each}}
</ul>
Including a Template
It is possible to include a template into another template.
For example, if we want to include the navbar.hbs
template, we use a “partial” include
like this:
{{> navbar }}
Note that we drop the .hbs
suffix when including this way.
Calling Template Helpers
There are a few template helpers defined in Bartholomew.
For example, to change a piece of text to all-caps, use the upper
helper:
{{ upper "hello" }}
The above will render HELLO
.
Note that you can create custom template helpers using Rhai scripts.
Defined Helper Functions
The following helper functions are provided with Bartholomew
upper STRING
: converts the given string to uppercaselower STRING
: converts the given string to lowercasedate_format STRING DATE
: Formats a date using the given string.date "%Y" page.head.date
. Use strftime format.now STRING
: Formats the current date using the given string. This uses the same format as above.trim STRING
: Remove whitespace from beginning and end of string.trunc UINT STRING
: Truncate the string to lengthUINT
.abbrev UINT STRING
: Shorten the string to UINT with elipses. For exampleabbrev 8 "Functions Example"
returnsFunct...
.plural INT SINGULAR_STRING PLURAL_STRING
: IfINT
is1
, return the singular form. Otherwise return plural:plural 1 "apple" "apples"
returnsapple
. But if we change1
to2
(or0
) it will returnapples
.
Values Reference
The following values are available in the template. This is formatted in YAML for readability. The four top-level objects are:
- page: The content for the current page
- site: Info about the entire site
- env: Information about the environment variables.
- request - Information about the browser, HTTP request and other spin information.
To reference a particular value, use dotted notation. For example, page
has a head
, which has the page’s title
.
To access the title, use {{ page.head.title }}
:
# Page holds data specific to the page that matches the URI. For example, the URI /foo loads page data from /content/foo.md
page:
# The info from the TOML head:
head:
date: "2022-01-11T20:08:47Z" # In templates, use `date_format "%B %m, %Y" page.head.date` to format
title: "WebAssembly Language Support Matrix" # The H1 title
description: "Tracking the programming languages that compile to WebAssembly (Wasm)."
template: "page"
tags: ["webassembly", "programming languages", "javascript", "python", "rust", "dotnet", "ruby"]
extra: # Remember that everything in extra is optional, so wrap in #if
author: "Fermyon Staff"
author_page: "/author/"
image: "/static/some/thing.png"
last_modified: "2022-01-11T20:08:47Z" # Only if the page is modified
body: "The HTML content"
published: true # Set to false if either manually disabled by author or if `date` is in the future
# Site holds sitewide data
site:
# Info keeps all of the information from `site.toml`
info:
title: "The site title"
base_url: "https://something" # Note no trailing slash
about: "Pithy site summary"
extra:
your_defined_field: "Value"
pages: # Metadata for every page on the site. Note that there is no guarantee that `body` will be set.
"/foo":
head:
date: "2022-01-11T20:08:47Z"
title: "Some title"
# These are all optional
description: "Some Description (if set)"
tags: ["tags", "if", "set"]
template: "template-if-set"
# user-defined extras go here
extras:
any: "extras go here"
published: true
"/bar":
head:
# These fields will always be set.
date: "2022-01-11T20:08:47Z"
title: "Some other title"
published: true
env: # Environment variables set in the Bartholomew Wasm module
request: # HTTP request data along with spin information.
Given the above, for example, you can write a template to create a link to the current page:
<a href="{{site.info.base_url}}{{env.PATH_INFO}}">{{page.head.title}}</a>
The above will output something like:
<a href="https://example.com/in-action">WebAssembly In Action</a>
Template Functions and Rhai Scripts
The following template functions are built into Bartholomew:
upper STRING
: Given a string, return an uppercase version (upper "foo"
printsFOO
)lower STRING
: Given a string, return a lowercase version (lower "Hello World"
printshello world
)now
: Return the current time in the format used by thedate
fielddate_format STRING DATE
: Given a format string and a date, format the date. (date_format "%B %d, %Y" "2022-01-11T20:08:47Z"
producesJanuary 11, 2022
)
Next, let’s dive into how site configuration works.
Did we miss something?
Let us know how we can improve this project, or contribute an edit to this page. We really appreciate your feedback, to help us build better tools.