Templates

Teddy Version: Latest

Working 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 authorId is specified in the page metadata, then Teddy will perform a lookup in $SITE_BASE/languages/{language}/contributors.json to 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 description page metadata value, if specified. If it is not specified, then the site description specified in $SITE_BASE/languages/{language}/metadata.json will 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 tags page metadata value, if specified. If it is not specified, then the site keywords specified in $SITE_BASE/languages/{language}/metadata.json will 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 name page metadata value, if specified. If it is not specified, then the site title specified in $SITE_BASE/languages/{language}/metadata.json will 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 description page metadata value, if specified. If it is not specified, then the site description specified in $SITE_BASE/languages/{language}/metadata.json will be used to populate this tag.
<meta property="og:image">
<meta property="og:url">
<meta property="og:type">
  • Example: article
  • Description: If the page is located within the collection directory, as defined in site.collection.pagesDir in the site.json site configuration, then the page type will resolve to article. For all other pages, the page type will resolve to website.
<meta property="article:modified_time">
  • Example: Sun Mar 02 2025 12:00:00 GMT+0000 (Greenwich Mean Time)
  • Description: If the page type is article then the date page 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 article then, as with the <meta name="author"> tag, if authorId is specified in the page metadata, Teddy will perform a lookup in $SITE_BASE/languages/{language}/contributors.json to 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 article then the translation of the first category key specified in the categories page metadata value will be used to populate this tag.
<meta property="article:tag">
  • Example: Victoria
  • Description: If the page type is article then a <meta property="article:tag"> tag will be generated for every unique tag specified in the tags page 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.

Contents