Templates
Teddy Version: LatestWorking with templates and the Mustache templating syntax.
Definition
A template is a HTML-based file that defines the layout and structure of a group of pages, and which utilises the Mustache templating syntax to inject localised metadata and content into the desired HTML elements.
Mustache
Mustache is a programming language-agnostic web template system. Mustache is described as a logic-less system because it lacks any control flow statements found in most programming languages, such as if conditional statements or loops. Mustache simply uses tags such as {{ metadata.title }} to lookup and then render the value of specified property keys. When applied to Teddy templates, Mustache tags are used to define where localised site metadata, page metadata and/or page content should be injected into HTML.
Localised Site Metadata
As described in the languages guide, during the build of your static site, all the localised JSON-based metadata files found in $SITE_BASE/languages/{language} are aggregated together along with localised URLs, and localised collection metadata (if applicable). The resulting aggregated localised metadata is then written to $SITE_BASE/build/{env}/{site.version}/languages/{language}.json. For example, the English language version of the demo TravelBook site will generate the following aggregated localised JSON-based metadata file in $TEDDY_BASE/sites/travelbook/build/{env}/{site.version}/languages/en.json during the build.
{
"content": {
"labels": {
"categories": "Categories",
"continueReading": "Continue Reading",
"languages": "Languages",
"loadMore": "Load More",
"notification": "No results found. Please try again.",
"recent": "Recent Articles",
"reset": "Reset Filters",
"search": "Search",
"searchPlaceholder": "Type and hit enter..."
}
},
"contributors": {
"default": "teddy",
"teddy": {
"name": "Teddy",
"url": "${pages.urls.about}"
}
},
"menus": {
"main": [
{
"name": "Home",
"url": "${pages.urls.home}"
},
{
"name": "About",
"url": "${pages.urls.about}"
},
{
"name": "Blog",
"url": "${pages.urls.blog}"
}
],
"footer": {
"quickLinks": {
"title": "Quick Links",
"links": [
{
"name": "Home",
"url": "${pages.urls.home}"
},
{
"name": "About",
"url": "${pages.urls.about}"
},
{
"name": "Blog",
"url": "${pages.urls.blog}"
}
]
},
"socialLinks": {
"title": "Social Links",
"links": [
{
"name": "Facebook",
"url": "{{{ urls.external.facebook }}}"
},
{
"name": "GitHub",
"url": "{{{ urls.external.github }}}"
},
{
"name": "Instagram",
"url": "{{{ urls.external.instagram }}}"
},
{
"name": "Twitter",
"url": "{{{ urls.external.twitter }}}"
}
]
}
},
"languages": [
{
"name": "English",
"url": "/en"
},
{
"name": "Japanese 日本語",
"url": "/ja"
},
{
"name": "Chinese 中文",
"url": "/zh-tw"
}
]
},
"metadata": {
"applicationName": "TravelBook",
"author": "Jillur Quddus",
"description": "Around the world with Teddy.",
"keywords": "africa, america, asia, australia, europe, holiday, flying, travel",
"title": "TravelBook"
},
"taxonomy": {
"categories": {
"africa": "Africa",
"asia": "Asia",
"australia": "Australia",
"europe": "Europe",
"north-america": "North America",
"south-america": "South America"
}
},
"urls": {
"external": {
"facebook": "https://www.facebook.com",
"github": "https://github.com",
"instagram": "https://www.instagram.com",
"themefisher": "https://github.com/themefisher/logbook-bootstrap",
"twitter": "https://x.com"
},
"assets": "/assets/0.0.1"
},
"collection": {
"metadata": {
"size": 15,
"pagination": {
"size": 10
},
"sort": {
"key": "date",
"order": "desc"
},
"pages": {
"head": [
{
"id": 0,
"name": "Serengeti National Park",
"description": "Tanzania is an East African country known for its vast wilderness areas. They include the plains of Serengeti National Park, a safari mecca populated by the 'big five' game (elephant, lion, leopard, buffalo, rhino), and Kilimanjaro National Park, home to Africa’s highest mountain. Offshore lie the tropical islands of Zanzibar, with Arabic influences, and Mafia, with a marine park home to whale sharks and coral reefs.",
"categoryLanguages": [
{
"id": "africa",
"name": "Africa"
}
],
"tags": [
"africa",
"serengeti",
"safari",
"Kilimanjaro",
"Zanzibar"
],
"date": "2025-03-04T12:00:00.000Z",
"displayDate": "4 March 2025",
"relUrl": "africa/tanzania",
"coverExists": true,
"cover": "assets/serengeti.jpg",
"author": "Teddy",
"authorUrl": "/about",
"content": "Lorem ipsum dolor sit amet consectetur..."
},
{
"id": 1,
"name": "Namib Desert",
"description": "Namibia, a country in southwest Africa, is distinguished by the Namib Desert along its Atlantic Ocean coast. The country is home to diverse wildlife, including a significant cheetah population. The capital, Windhoek, and coastal town Swakopmund contain German colonial-era buildings such as Windhoek's Christuskirche, built in 1907. In the north, Etosha National Park’s salt pan draws game including rhinos and giraffes.",
"categoryLanguages": [
{
"id": "africa",
"name": "Africa"
}
],
"tags": [
"africa",
"cheetah",
"Windhoek",
"Swakopmund",
"salt"
],
"date": "2025-03-03T12:00:00.000Z",
"displayDate": "3 March 2025",
"relUrl": "africa/namibia",
"coverExists": true,
"cover": "assets/desert.jpg",
"author": "Teddy",
"authorUrl": "/about",
"content": "Lorem ipsum dolor sit amet consectetur..."
},
{
"id": 2,
"name": "Mosi-oa-Tunya",
"description": "Zambia, in southern Africa, is a landlocked country of rugged terrain and diverse wildlife, with many parks and safari areas. On its border with Zimbabwe is famed Victoria Falls – indigenously called Mosi-oa-Tunya, or 'Smoke That Thunders' – plunging a misty 108m into narrow Batoka Gorge. Spanning the Zambezi River just below the falls is Victoria Falls Bridge, a spectacular viewpoint.",
"categoryLanguages": [
{
"id": "africa",
"name": "Africa"
}
],
"tags": [
"africa",
"Zambezi",
"Victoria",
"Mosi-oa-Tunya",
"Batoka"
],
"date": "2025-03-02T12:00:00.000Z",
"displayDate": "2 March 2025",
"relUrl": "africa/zambia",
"coverExists": true,
"cover": "assets/victoria-falls.jpg",
"author": "Teddy",
"authorUrl": "/about",
"content": "Lorem ipsum dolor sit amet consectetur..."
},
{
"id": 3,
"name": "Savannah Grasslands",
"description": "Kenya is a country in East Africa with coastline on the Indian Ocean. It encompasses savannah, lakelands, the dramatic Great Rift Valley and mountain highlands. It is also home to wildlife like lions, elephants and rhinos. From Nairobi, the capital, safaris visit the Maasai Mara Reserve, known for its annual wildebeest migrations, and Amboseli National Park, offering views of Tanzania's 5,895m Mt. Kilimanjaro.",
"categoryLanguages": [
{
"id": "africa",
"name": "Africa"
}
],
"tags": [
"africa",
"savannah",
"lakelands",
"lion",
"elephant"
],
"date": "2025-03-01T12:00:00.000Z",
"displayDate": "1 March 2025",
"relUrl": "africa/kenya",
"coverExists": true,
"cover": "assets/savannah.jpg",
"author": "Teddy",
"authorUrl": "/about",
"content": "Lorem ipsum dolor sit amet consectetur..."
},
{
"id": 4,
"name": "Kyoto Temples",
"description": "Japan is an island country in East Asia. Located in the Pacific Ocean off the northeast coast of the Asian mainland, it is bordered on the west by the Sea of Japan and extends from the Sea of Okhotsk in the north to the East China Sea in the south.",
"categoryLanguages": [
{
"id": "asia",
"name": "Asia"
}
],
"tags": [
"asia",
"sushi",
"samurai",
"hokkaido",
"kyushu",
"honshu",
"anime",
"kyoto",
"temple",
"fuji",
"onsen",
"kanji"
],
"date": "2025-02-04T12:00:00.000Z",
"displayDate": "4 February 2025",
"relUrl": "asia/japan",
"coverExists": true,
"cover": "assets/kyoto.jpg",
"author": "Teddy",
"authorUrl": "/about",
"content": "Lorem ipsum dolor sit amet consectetur..."
},
{
"id": 5,
"name": "Bustling Hong Kong",
"description": "Hong Kong is a special administrative region of China. With 7.4 million residents of various nationalities in a 1,104-square-kilometre territory, Hong Kong is the fourth most densely populated region in the world.",
"categoryLanguages": [
{
"id": "asia",
"name": "Asia"
}
],
"tags": [
"asia",
"china",
"sar"
],
"date": "2025-02-03T12:00:00.000Z",
"displayDate": "3 February 2025",
"relUrl": "asia/hong-kong",
"coverExists": true,
"cover": "assets/hk.jpg",
"author": "Teddy",
"authorUrl": "/about",
"content": "Lorem ipsum dolor sit amet consectetur..."
},
{
"id": 6,
"name": "Kuala Lumpur",
"description": "Malaysia is a Southeast Asian country occupying parts of the Malay Peninsula and the island of Borneo. It's known for its beaches, rainforests and mix of Malay, Chinese, Indian and European cultural influences. The capital, Kuala Lumpur, is home to colonial buildings, busy shopping districts such as Bukit Bintang and skyscrapers such as the iconic, 451m-tall Petronas Twin Towers.",
"categoryLanguages": [
{
"id": "asia",
"name": "Asia"
}
],
"tags": [
"asia",
"petronas",
"malay",
"borneo"
],
"date": "2025-02-02T12:00:00.000Z",
"displayDate": "2 February 2025",
"relUrl": "asia/malaysia",
"coverExists": true,
"cover": "assets/kuala-lumpur.jpg",
"author": "Teddy",
"authorUrl": "/about",
"content": "Lorem ipsum dolor sit amet consectetur..."
},
{
"id": 7,
"name": "Sizzling Singapore",
"description": "Singapore, officially the Republic of Singapore, is an island country and city-state in Southeast Asia. The country's territory comprises one main island, 63 satellite islands and islets, and one outlying islet.",
"categoryLanguages": [
{
"id": "asia",
"name": "Asia"
}
],
"tags": [
"asia",
"strait",
"republic",
"island"
],
"date": "2025-02-01T12:00:00.000Z",
"displayDate": "1 February 2025",
"relUrl": "asia/singapore",
"coverExists": true,
"cover": "assets/singapore.jpg",
"author": "Teddy",
"authorUrl": "/about",
"content": "Lorem ipsum dolor sit amet consectetur..."
},
{
"id": 8,
"name": "Hobbiton",
"description": "New Zealand is an island country in the southwestern Pacific Ocean. It consists of two main landmasses—the North Island and the South Island —and over 700 smaller islands.",
"categoryLanguages": [
{
"id": "australia",
"name": "Australia"
}
],
"tags": [
"australia",
"lotr",
"hobbits",
"wellington",
"auckland"
],
"date": "2025-01-01T12:00:00.000Z",
"displayDate": "1 January 2025",
"relUrl": "australia/new-zealand",
"coverExists": true,
"cover": "assets/hobbiton.jpg",
"author": "Teddy",
"authorUrl": "/about",
"content": "Lorem ipsum dolor sit amet consectetur..."
},
{
"id": 9,
"name": "Northern Lights",
"description": "Finland is a Northern European nation bordering Sweden, Norway and Russia. Its capital, Helsinki, occupies a peninsula and surrounding islands in the Baltic Sea. Helsinki is home to the 18th-century sea fortress Suomenlinna, the fashionable Design District and diverse museums. The Northern Lights can be seen from the country's Arctic Lapland province, a vast wilderness with national parks and ski resorts.",
"categoryLanguages": [
{
"id": "europe",
"name": "Europe"
}
],
"tags": [
"europe",
"helsinki",
"baltic",
"Suomenlinna",
"Lapland"
],
"date": "2024-12-02T12:00:00.000Z",
"displayDate": "2 December 2024",
"relUrl": "europe/finland",
"coverExists": true,
"cover": "assets/northern-lights.jpg",
"author": "Teddy",
"authorUrl": "/about",
"content": "Lorem ipsum dolor sit amet consectetur..."
}
]
},
"categories": [
{
"id": "africa",
"name": "Africa",
"count": 4
},
{
"id": "asia",
"name": "Asia",
"count": 4
},
{
"id": "australia",
"name": "Australia",
"count": 1
},
{
"id": "europe",
"name": "Europe",
"count": 2
},
{
"id": "north-america",
"name": "North America",
"count": 1
},
{
"id": "south-america",
"name": "South America",
"count": 3
}
]
}
}
}
Accessing Localised Site Metadata
Templates can access and retrieve aggregated localised site metadata values by using Mustache tags and referencing the nested property key of the metadata value required. For example, given the aggregated localised JSON-based metadata generated for the English language version of the demo TravelBook site provided above, the following Mustache tags will render the following values.
- {{ metadata.title }} will render
TravelBook. - {{ taxonomy.categories.south-america }} will render
South America. - {{{ urls.assets }}} will render
/assets. - {{{ urls.external.github }}} will render
https://github.com. - {{ collection.metadata.size }} will render
15.
All variables are HTML-escaped by default. To render unescaped HTML, for example URLs in the urls namespace, use the triple mustache which uses three pairs of curly braces, for example {{{ urls.external.github }}}.
Render Lists
Mustache also supports the ability to iterate over lists/arrays and render each object in the list. For example, the default Bear theme utilises the following Mustache syntax, found in $TEDDY_BASE/themes/bear/templates/partials/body/body-menu.html, to iterate over a list of main menu items to create main menu HTML elements.
{{ #menus.main }}
<li class="nav-item">
<a class="nav-link" href="{{{ url }}}">{{ name }}</a>
</li>
{{ /menus.main }}
Mustache Partials
Mustache also supports the ability to include and combine different templates into a single template through the use of Mustache partials. This is particularly useful if you wish to create separate templates for common sections or components that are shared across multiple HTML pages. For example, you may choose to create a template specifically responsible for rendering the page main menu, and another template specifically responsible for rendering the page footer. You can then re-use these component-based templates by utilising Mustache partials to include them into aggregated templates. This approach also makes it easier for developers to maintain themes, as component-based templates can be updated independent of each other. For example, the default Bear theme contains a template named page.html, found in $TEDDY_BASE/themes/bear/templates/page.html, that defines the base layout and structure of general pages that apply the Bear theme, as follows.
<!DOCTYPE html>
<html lang="${page.metadata.language}">
<head>
<!-- Metadata -->
{{> partials/head/head-metadata.html }}
<!-- Favicon -->
{{> partials/head/head-favicon.html }}
<!-- Fonts -->
{{> partials/head/head-fonts.html }}
<!-- CSS -->
{{> partials/head/head-css.html }}
</head>
<body>
<!-- Menu -->
{{> partials/body/body-menu.html }}
<!-- Page Content -->
<section class="pt-5 pb-5">
<div class="container">
<div class="row">
<div class="col-lg-12">
${page.content}
</div>
</div>
</div>
</section>
<!-- Footer -->
{{> partials/body/body-footer.html }}
<!-- Javascript -->
{{> partials/body/body-js.html }}
</body>
</html>
This template uses Mustache partials to include section-specific templates, for example {{> partials/head/head-favicon.html }} to include the template responsible for embedding the site favicon, {{> partials/body/body-menu.html }} to include the template responsible for rendering the main menu, and {{> partials/body/body-js.html }} to include the template responsible for embedding client-side JavaScript files, all of which are shared across all pages of static sites that apply this theme.
Page Metadata
As described in the pages guide, a page is a language-specific markdown-based flat-file that contains both page content and metadata. When a static site is built, each language-specific markdown-based page is converted into HTML and injected into a specified theme HTML template. Relevant language-specific site and page metadata is then also injected to generate the final HTML file representing the page in question. For example, the pages comprising the demo TravelBook site can be found in $TEDDY_BASE/sites/travelbook/pages. An example English-language blog post page from this demo site, found in $TEDDY_BASE/sites/travelbook/pages/blog/africa/zambia/post.en.md, is provided below.
---
name: Mosi-oa-Tunya
enabled: true
description: Zambia, in southern Africa, is a landlocked country of rugged terrain and diverse wildlife, with many parks and safari areas. On its border with Zimbabwe is famed Victoria Falls – indigenously called Mosi-oa-Tunya, or 'Smoke That Thunders' – plunging a misty 108m into narrow Batoka Gorge. Spanning the Zambezi River just below the falls is Victoria Falls Bridge, a spectacular viewpoint.
categories: africa
tags: Zambezi, Victoria, Mosi-oa-Tunya, Batoka
authorId: teddy
date: 2025-03-02 12:00:00
cover: assets/victoria-falls.jpg
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit...
The localised page metadata is defined in the markdown frontmatter, i.e. the metadata enclosed between the --- separators at the head of the markdown document.
Accessing Page Metadata
Teddy provides the ability for theme templates to access the page metadata values defined in the page frontmatter by referencing the page.metadata object using JavaScript-based string interpolation. Using the example markdown-based blog post page provided above, the following JavaScript placeholders will resolve to the following values.
- ${page.metadata.name} will resolve to
Mosi-oa-Tunya. - ${page.metadata.description} will resolve to
Zambia, in southern Africa, is a landlocked country.... - ${page.metadata.date} will resolve to
2 March 2025.
Please read the pages guide for further details on page metadata including reserved and custom page metadata keys and placeholders.
Page Content
To access the page content itself in templates, you can use the ${page.content} placeholder as follows.
- ${page.content} will resolve to
Lorem ipsum dolor sit amet, consectetur adipiscing elit....
Open Graph Protocol
If site.html.inject.metadata is set to true in your site.json site configuration, then there is no need to define Open Graph protocol tags in your HTML templates. Instead, Teddy will automatically generate and inject the following metadata and Open Graph tags into your HTML pages.
<meta name="author">
- Example: Teddy
- Description: If
authorIdis specified in the page metadata, then Teddy will perform a lookup in$SITE_BASE/languages/{language}/contributors.jsonto retrieve the author name. Otherwise the default author name will be used to populate this tag.
<meta name="description">
- Example: Zambia, in southern Africa, is a landlocked country of rugged terrain and diverse wildlife…
- Description: Based on the
descriptionpage metadata value, if specified. If it is not specified, then the site description specified in$SITE_BASE/languages/{language}/metadata.jsonwill be used to populate this tag.
<meta name="keywords">
- Example: Zambezi, Victoria, Mosi-oa-Tunya, Batoka,africa, america, asia, australia, europe, holiday, flying, travel
- Description: Based on the
tagspage metadata value, if specified. If it is not specified, then the site keywords specified in$SITE_BASE/languages/{language}/metadata.jsonwill be used to populate this tag.
<meta property="og:site_name">
- Example: TravelBook
- Description: Based on the site title specified in
$SITE_BASE/languages/{language}/metadata.json.
<meta property="og:title">
- Example: Mosi-oa-Tunya | TravelBook
- Description: Based on the
namepage metadata value, if specified. If it is not specified, then the site title specified in$SITE_BASE/languages/{language}/metadata.jsonwill be used to populate this tag.
<meta property="og:description">
- Example: Zambia, in southern Africa, is a landlocked country of rugged terrain and diverse wildlife…
- Description: Based on the
descriptionpage metadata value, if specified. If it is not specified, then the site description specified in$SITE_BASE/languages/{language}/metadata.jsonwill be used to populate this tag.
<meta property="og:image">
- Example: https://demo.teddyful.com/blog/africa/zambia/assets/victoria-falls.jpg
- Description: Based on the
ogorcoverpage metadata values, if specified. If neither are specified, then the default Open Graph image defined insite.assets.custom.images.og.defaultin thesite.jsonsite configuration will be used to populate this tag, if specified.
<meta property="og:url">
- Example: https://demo.teddyful.com/blog/africa/zambia/
- Description: The fully resolved absolute URL to the page, generated using a combination of the values defined in
site.web.{env}.http.secureandsite.web.{env}.domainrespectively in thesite.jsonsite configuration, and the relative path to the page itself.
<meta property="og:type">
- Example: article
- Description: If the page is located within the collection directory, as defined in
site.collection.pagesDirin thesite.jsonsite configuration, then the page type will resolve toarticle. For all other pages, the page type will resolve towebsite.
<meta property="article:modified_time">
- Example: Sun Mar 02 2025 12:00:00 GMT+0000 (Greenwich Mean Time)
- Description: If the page type is
articlethen thedatepage metadata value will be used to populate this tag, if specified. If it is not specified, then the file system date that the page was last modified will be used.
<meta property="article:author">
- Example: Teddy
- Description: If the page type is
articlethen, as with the<meta name="author">tag, ifauthorIdis specified in the page metadata, Teddy will perform a lookup in$SITE_BASE/languages/{language}/contributors.jsonto retrieve the author name. Otherwise the default author name will be used to populate this tag.
<meta property="article:section">
- Example: Africa
- Description: If the page type is
articlethen the translation of the first category key specified in thecategoriespage metadata value will be used to populate this tag.
<meta property="article:tag">
- Example: Victoria
- Description: If the page type is
articlethen a<meta property="article:tag">tag will be generated for every unique tag specified in thetagspage metadata value.
System Assets
If site.html.inject.systemAssets is set to true in your site.json site configuration, then <script> tags will be automatically generated and injected into your HTML pages for each JavaScript asset specified in system.assets.js in the system.json system configuration file.
