Pages
Teddy Version: LatestCreating new pages and defining & accessing page metadata.
Definition
A page is a language-specific markdown-based flat-file that contains both content and metadata that is converted into HTML when a static site is built. As described in the sites guide, 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. This stage of the build pipeline is illustrated in the following diagram.

Example
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...
Frontmatter
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.
---
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
---
Content
The localised page content is provided by the content of the markdown document that resides after the frontmatter.
Lorem ipsum dolor sit amet, consectetur adipiscing elit...
Site Page Structure
For the purposes of this guide, we will hereafter refer to your site directory, for example $TEDDY_BASE/sites/travelbook, as $SITE_BASE. The $SITE_BASE/pages directory contains the language-specific content for each of the pages that comprise your site. Each page is a markdown-based flat-file that must conform to the following file naming convention: {template.name}.{language.code}.md, for example page.en.md. The directory structure in $SITE_BASE/pages will reflect the page structure of your static site when it is built. Each unique page must exist in its own directory. For example, the demo TravelBook site has the following pages directory structure in $TEDDY_BASE/sites/travelbook/pages.
$SITE_BASE/
├── languages/
├── pages/
│ └── about/
│ └── about.en.md <-- English about page
│ └── about.ja.md <-- Japanese about page
│ └── about.zh-tw.md <-- Traditional Chinese about page
│ └── blog/
│ └── africa/
│ └── kenya/
| └── post.en.md <-- English blog post
| └── post.ja.md <-- Japanese blog post
| └── post.zh-tw.md <-- Traditional Chinese blog post
│ └── namibia/
| └── post.en.md
| └── post.ja.md
| └── post.zh-tw.md
│ └── tanzania/...
│ └── zambia/...
│ └── asia/
│ └── hong-kong/...
│ └── japan/...
│ └── malaysia/...
│ └── singapore/...
│ └── australia/
│ └── new-zealand/...
│ └── europe/
│ └── finland/...
│ └── norway/...
│ └── north-america/
│ └── canada/...
│ └── south-america/
│ └── bolivia/...
│ └── chile/...
│ └── peru/...
│ └── blog.en.md <-- English blog listing page
│ └── blog.ja.md <-- Japanese blog listing page
│ └── blog.zh-tw.md <-- Traditional Chinese blog listing page
│ └── page.en.md <-- English home page
│ └── page.ja.md <-- Japanese home page
│ └── page.zh-tw.md <-- Traditional Chinese home page
├── site.json
When the demo TravelBook site is built, the generated static site will have the following structure found in $TEDDY_BASE/sites/travelbook/public/{env}.
$SITE_BASE/public/{env}/
├── about/ <-- default language pages
│ └── index.html
├── blog/ <-- default language pages
│ └── africa/
│ └── kenya/index.html
│ └── namibia/index.html
│ └── tanzania/index.html
│ └── zambia/index.html
│ └── asia/
│ └── hong-kong/index.html
│ └── japan/index.html
│ └── malaysia/index.html
│ └── singapore/index.html
│ └── australia/
│ └── new-zealand/index.html
│ └── europe/
│ └── finland/index.html
│ └── norway/index.html
│ └── north-america/
│ └── canada/index.html
│ └── south-america/
│ └── bolivia/index.html
│ └── chile/index.html
│ └── peru/index.html
│ └── index.html
│ └── en/ <-- English language pages
│ └── about/index.html
│ └── blog/...
│ └── index.html <-- English language home page
│ └── ja/ <-- Japanese language pages
│ └── about/index.html
│ └── blog/...
│ └── index.html <-- Japanese language home page
│ └── zh-tw/ <-- Traditional Chinese language pages
│ └── about/index.html
│ └── blog/...
│ └── index.html <-- Traditional Chinese language home page
├── index.html <-- default language home page
The HTML pages for each language-specific subsite are created in $SITE_BASE/public/{env}/{language}. Furthermore, HTML pages corresponding to the default language are duplicated in the root of the generated static site. Continuing with the example of the demo TravelBook site, its various pages and resources can be accessed at the following URLs (assuming a base URL of https://demo.teddyful.com).
Home Page
- Default language (English): https://demo.teddyful.com
- Japanese 日本語: https://demo.teddyful.com/ja/
- Traditional Chinese 中文: https://demo.teddyful.com/zh-tw/
About Page
- Default language (English): https://demo.teddyful.com/about/
- Japanese 日本語: https://demo.teddyful.com/ja/about/
- Traditional Chinese 中文: https://demo.teddyful.com/zh-tw/about/
Blog Listing Page
- Default language (English): https://demo.teddyful.com/blog/
- Japanese 日本語: https://demo.teddyful.com/ja/blog/
- Traditional Chinese 中文: https://demo.teddyful.com/zh-tw/blog/
Blog Article (e.g. Zambia)
- Default language (English): https://demo.teddyful.com/blog/africa/zambia/
- Japanese 日本語: https://demo.teddyful.com/ja/blog/africa/zambia/
- Traditional Chinese 中文: https://demo.teddyful.com/zh-tw/blog/africa/zambia/
Page File Name
As stated above, each page in $SITE_BASE/pages is a markdown-based flat-file that must conform to the following file naming convention: {template.name}.{language.code}.md, for example page.en.md.
Page Template Name
The template.name in the page file name must correspond exactly to the name of a HTML template found in $TEDDY_BASE/themes/{theme.name}/templates, for example page.html. When your static site is built, each language-specific markdown-based page is converted into HTML and injected into the specified theme HTML template. For example, the content of the demo TravelBook blog article markdown page found at $TEDDY_BASE/sites/travelbook/pages/blog/africa/zambia/post.en.md will be converted into HTML and injected into the post.html template found in $TEDDY_BASE/themes/bear/templates/post.html. The final HTML page will be found in $TEDDY_BASE/sites/travelbook/public/{env}/en/blog/africa/zambia/index.html.
Page Metadata
Accessing Page Metadata
Teddy provides the ability for your markdown-based pages and HTML-based 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.
Reserved Metadata Keys
Teddy reserves the following page metadata keys.
name
- Frontmatter Key:
name - Type:
string - Required: Yes
- Example:
Mosi-oa-Tunya - Placeholder: ${page.metadata.name}
- Description: The page name that will be used to populate the HTML
<title>and<meta property="og:title">tags if specified. The page name is also typically used to display the post name in a blog listing page, blog post header or hero element, or similar.
enabled
- Frontmatter Key:
enabled - Type:
boolean - Required: Yes
- Example:
true - Placeholder: ${page.metadata.enabled}
- Description: Used to determine whether the page will be built. A page must explicitly contain the
enabledkey in its frontmatter with its value set totruein order to be built. If theenabledkey is missing, or if it is set to the valuefalse, then Teddy will ignore the page and it will not be built.
index
- Frontmatter Key:
index - Type:
boolean - Required: No
- Example:
false - Placeholder: ${page.metadata.index}
- Description: If the
indexkey is specified in the page frontmatter and it is set to the valuefalse, then the page, if it is contained within the specified collection directory, will NOT be indexed nor added to the client-side JavaScript-based FlexSearch document store.
description
- Frontmatter Key:
description - Type:
string - Required: No, but highly recommended
- Example:
Zambia, in southern Africa, is a landlocked country... - Placeholder: ${page.metadata.description}
- Description: A brief description of the page that will be used to populate the HTML
<meta name="description">and<meta property="og:description">tags if specified. The page description is also typically used to display the post description in a blog listing page, blog post header or hero element, or similar.
categories
- Frontmatter Key:
categories - Type:
string - Required: No, but highly recommended
- Example:
africa - Placeholder: ${page.metadata.categories}
- Description: A comma-delimited list of category keys that this page belongs to. The category key(s) defined here must exist, with exactly the same name and case, in the
site.collection.taxonomy.categoriesarray defined in thesite.jsonsite configuration file. The page categories are also typically used to filter posts by category in a blog listing page or similar. Note that when retrieving the page categories using the ${page.metadata.categories} placeholder, a localised comma-delimited list of categories will be returned using the translations defined in$SITE_BASE/languages/{language}/taxonomy.json, for exampleAfrica. Also note that ifsite.collection.enabledis set totruein thesite.jsonsite configuration file for your site, then the page category keys will be merged with the page tags to enable category and tag-based filtering of pages located within the collection.
tags
- Frontmatter Key:
tags - Type:
string - Required: No
- Example:
Zambezi, Victoria, Mosi-oa-Tunya, Batoka - Placeholder: ${page.metadata.tags}
- Description: A comma-delimited list of tags and keywords that will be used to populate the HTML
<meta name="keywords">and<meta property="article:tag"tags if specified. The page tags are also typically used to filter posts by tag in a blog listing page or similar.
authorId
- Frontmatter Key:
authorId - Type:
string - Required: No
- Example:
teddy - Placeholder: ${page.metadata.authorId}
- Description: The ID, as defined in
$SITE_BASE/languages/{language}/contributors.json(see the languages guide for further information), of the primary author of the page. The page author is typically used to display the author name in a blog listing page, blog post header or hero element, or similar. If theauthorkey is not defined, then the default author ID specified in$SITE_BASE/languages/{language}/contributors.jsonwill be used as the page author ID.
date
- Frontmatter Key:
date - Type:
string - Required: No
- Example:
2025-03-02 12:00:00 - Placeholder: ${page.metadata.date}
- Description: The date and time that the page was last updated, which will be used to populate the HTML
<meta property="article:modified_time">Open Graph tag. The page date is also typically used to display the post date in a blog listing page, blog post header or hero element, or similar. If thedatekey is not defined, then the file system date that the page markdown file was last modified will be used as the page date. Note that when retrieving the page date using the ${page.metadata.date} placeholder, the user-friendlyDD MMMM YYYYformat of the date will be returned, for example28 February 2025.
hero
- Frontmatter Key:
hero - Type:
string - Required: No
- Example:
og/og-default.jpg - Placeholder: ${page.metadata.hero}
- Description: A path to an image file, relative to
{urls.assets}/images(see the aggregated localised metadata section in the languages guide), which can be used as the page hero image if applicable. If theheroimage is not defined, then the default hero image specified insite.assets.custom.images.hero.defaultin thesite.jsonsite configuration file will be used, if specified.
cover
- Frontmatter Key:
cover - Type:
string - Required: No
- Example:
assets/victoria-falls.jpg - Placeholder: ${page.metadata.cover}
- Description: A path to an image file, relative to the location of the page itself, that can be used as the page cover image if applicable. The cover image is typically used to display the post image in a blog listing page, blog post header or hero element, or similar.
og
- Frontmatter Key:
og - Type:
string - Required: No
- Example:
assets/victoria-falls.jpg - Placeholder: ${page.metadata.og}
- Description: A path to an image file, relative to the location of the page itself, that will be used to populate the HTML
<meta property="og:image">Open Graph tag if specified. If theogimage is not defined, then thecoverimage will be used as the Open Graph image for the page if specified. If neither theognor thecoverimages are defined, then the default Open Graph image specified insite.assets.custom.images.og.defaultin thesite.jsonsite configuration file will be used, if specified. Thus the order of precedence isog>cover>site.assets.custom.images.og.default.
Additional Placeholders
In addition to the page metadata placeholders listed above, Teddy also provides placeholders for other common page-specific metadata, as follows.
- ${page.metadata.author.name} will perform a lookup of the page author ID in
$SITE_BASE/languages/{language}/contributors.jsonand return the page author name, for exampleTeddy. - ${page.metadata.author.url} will perform a lookup of the page author ID in
$SITE_BASE/languages/{language}/contributors.jsonand return the page author profile URL, for examplehttps://demo.teddyful.com/about. - ${page.metadata.author.role} will perform a lookup of the page author ID in
$SITE_BASE/languages/{language}/contributors.jsonand return the page author role or job title, for exampleBlogger. - ${page.metadata.author.description} will perform a lookup of the page author ID in
$SITE_BASE/languages/{language}/contributors.jsonand return the page author description. - ${page.metadata.author.avatar} will perform a lookup of the page author ID in
$SITE_BASE/languages/{language}/contributors.jsonand return the page author avatar image URL. - ${page.metadata.language} will return the page language code, for example
en. - ${page.metadata.title} will return the page title as a concatenation of the page name and the site name, for example
Mosi-oa-Tunya | TravelBook. - ${page.metadata.type} will return the page type. If the page is located within the collection directory, as defined in
site.collection.pagesDirin thesite.jsonsite configuration file, then the page type will bearticle, otherwise it will bewebsite. The page type is also used to populate the HTML<meta property="og:type">Open Graph tag. - ${page.metadata.url} will return the fully resolved absolute URL to the page, for example
https://demo.teddyful.com/blog/africa/zambia/.
Custom Metadata Keys
Beyond the reserved page metadata keys, you may define and subsequently access your own custom page metadata keys. To do this, simply specify your custom metadata key-value pair in the page frontmatter. The value associated with the custom key can then be accessed and retrieved in the exact same way as accessing reserved metadata key values i.e. reference the page.metadata object using a placeholder. For example, if you were to define draft: true in the page frontmatter, its value can be accessed using the ${page.metadata.draft} placeholder.
Page Content
Accessing Page Content
To access the page content itself in your HTML-based theme templates, you can use the ${page.content} placeholder as follows.
- ${page.content} will resolve to
Lorem ipsum dolor sit amet, consectetur adipiscing elit....
Localised Page URLs
Teddy also provides the ability for your markdown-based pages, HTML-based theme templates and JSON-based localised metadata files to access and retrieve localised page URL values. As described above, the directory structure in $SITE_BASE/pages will reflect the page structure of your static site when it is built. To avoid hardcoding localised page URLs in your markdown-based pages, HTML-based theme templates and JSON-based localised metadata files, you can reference the pages.urls object using JavaScript-based string interpolation. For example, using the demo TravelBook site, the following placeholders will resolve to the following URL values dependent upon the active language.
- ${pages.urls.home} will resolve to
/for the default language of the site (English),/jafor the Japanese language version of the site, and/zh-twfor the Traditional Chinese language version of the site. - ${pages.urls.about} will resolve to
/aboutfor the default language of the site (English),/ja/aboutfor the Japanese language version of the site, and/zh-tw/aboutfor the Traditional Chinese language version of the site. - ${pages.urls.blog} will resolve to
/blogfor the default language of the site (English),/ja/blogfor the Japanese language version of the site, and/zh-tw/blogfor the Traditional Chinese language version of the site. - ${pages.urls.blog.africa.zambia} will resolve to
/blog/africa/zambiafor the default language of the site (English),/ja/blog/africa/zambiafor the Japanese language version of the site, and/zh-tw/blog/africa/zambiafor the Traditional Chinese language version of the site.
Document Store
If site.collection.enabled is set to true in the site.json site configuration file for your site, then all pages located within the directory specified in site.collection.pagesDir, relative to $SITE_BASE/pages, will be indexed and added to a JavaScript-based FlexSearch document store to enable free-text searching, and category & tag-based filtering, of those pages. To disable indexing at the page-level, specify the index key in the page frontmatter and set it to the value false. For example, the demo TravelBook site is configured in $TEDDY_BASE/sites/travelbook/site.json to index the page name, description, tags and content, thus enabling users to perform free-text search queries across, and category-based filtering of, its travel-related blog posts (recall that, as described above, page category keys will be merged with the page tags during indexing, thus there is no need to add categories to the FlexSearch document store configuration object). Please read the site configuration and search guides respectively for further details.
