Skip to main content Link Search Menu Expand Document (external link)

Using Templates

Templates can be simple HTML.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Site Title Here</title>
</head>

<body>
    <h1>heading here</h1>
    <p>a paragraph here</p>
</body>

But are most powerful when you use the built in Mustache Tags to dynamically load things.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{{#title}} {{title}} | {{/title}}{{site_title}}</title>
</head>

<body>
    <h1>{{title}}</h1>
    {{{content}}}
</body>

In this example the {{#title}} {{title}} | {{/title}} portion uses Mustache’s false check to determine if the current URL has a title defined in its Content File’s Frontmatter. If so then it will output the value of the title.

---
title: About Page
---

# About Page

About content here.

The site title is then output from the Globally defined site_title in the config.json file.

{
    "globals": {
        "domain"                : "website.com",
        "site_title"            : "A Website, On Mars",
        "site_description"      : "a website that has stuff on it",
        "author"                : "A. Person"
    },

}

Further down in the body the title is output as a heading for the page. And the page’s content pulled from its Content File’s content area is output.

Please note that the content has three {{{}}} around it, because it is not just outputting raw text but instead formatted html. This is a convention of Mustache’s syntax. If you forget the extra bracket it will not render correctly.

Rendering fully, the final output from the above snippets would look like this.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>About Page | A Website, On Mars</title>
</head>

<body>
    <h1>About Page</h1>
    <p>About content here.</p>
</body>

This enables you to define a value one time and reuse it elsewhere, or to pull in a dynamic value that may change from URL to URL. In this instance, if you navigated away to another page then the title and content values would output different information automatically.

Page Templates

They are dynamically loaded for Home, and first-level URLs.

domain.com/
domain.com/about
domain.com/contact
domain.com/work
domain.com/blog

The General Page Template can be found at /themes/{active-theme}/page.ms

Specific Page Templates can be found at /themes/{active-theme}/pages/page-title-here.ms

To understand how Templates are loaded and overridden, please check out the Template Cascade.

Post Templates

They are dynamically loaded for second-level URLs, and nest under their respective content type parent.

domain.com/blog/hello-mars/
domain.com/blog/goodbye-pluto/
domain.com/work/moby-dick/
domain.com/work/gallery-show-seven/

The General Post Template can be found at /themes/{active-theme}/post.ms

Specific Post Type Templates can be found at /themes/{active-theme}/post-{post-type}.ms

Specific Post Templates can be found at /themes/{active-theme}/{post-type}/{specific-post-title-here}.ms

To understand how Templates are loaded and overridden, please check out the Template Cascade.

Post Feed Templates

They are dynamically loaded for a valid Post Type, followed by feed in the second-level, and a valid Format in the third-level

domain.com/blog/feed/rss/
domain.com/blog/feed/json/
domain.com/writing/feed/rss/
domain.com/writing/feed/json/

All Feeds come in two formats: Atom 1.0 RSS & JSON Feed.

By default the Post Type blog is enabled to have a Feed. Any other Post Types you create must have their respective Feeds enabled through your config.json file. See Configuration for more details.

The General Feed Template can be found at /themes/{active-theme}/feed.ms

Specific Feed by Post Type Templates can be found at /themes/{active-theme}/feed{format}-{post-type}.ms

If you do not include a Feed Template of any kind in your theme, the format specific one baked into Charlie will be used.

The RSS version contains the following code to model from:

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

<title>{{author}}'s {{post.type}} Feed</title>
<subtitle>{{site_description}}</subtitle>
<link href="http://{{domain}}/feed/" hreflang="en" rel="self" type="application/atom+xml"/>
<link href="http://{{domain}}/" hreflang="en" rel="alternate" type="text/html"/>

<updated>2012-07-15T10:50:43+10:00</updated>
<generator uri="http://charliecms.com/" version="1.0">Charlie</generator>

<author>
<name>{{author}}</name>
<uri>http://{{domain}}</uri>
</author>

<id>tag:{{domain}},2012:/feed/</id>
<rights> {{current_year}} {{author}}</rights>

{{#post.feed}}
		{{#item}}

		<entry>
			<title>{{title}}</title>
			<id>{{id}}</id>
			<updated>{{date}}</updated>
			<link rel="alternate" type="text/html" href="{{link}}" />
			<content type="xhtml" xml:lang="en">
				<div xmlns="http://www.w3.org/1999/xhtml">

					<summary>{{summary}}</summary>

				</div>
		   </content>
		</entry>

		{{/item}}
{{/post.feed}}

</feed>

The JSON version contains the following code to model from:

{
  "version": "https://jsonfeed.org/version/1",
  "user_comment": "This feed allows you to read the posts from this site in any feed reader that supports the JSON Feed format. To add this feed to your reader, copy the following URL — https://jsonfeed.org/feed.json — and add it your reader.",
  "title": "JSON Feed",
  "description": "{{site_description}}",
  "home_page_url": "{{domain}}",
  "feed_url": "https://jsonfeed.org/feed.json",
  "author": {
    "name": "{{author}}",
    "url": "{{domain}}"
  },
  "items": [
  {{#post.feed}}
	{{#item}}
    {
      "title": "{{title}}",
      "date_published": "2017-05-17T08:02:12-07:00",
      "id": "https://jsonfeed.org/2017/05/17/announcing_json_feed",
      "url": "{{link}}",
      "content_html": "{{content}}"
    }
	{{/item}}
  ]
  {{/post.feed}}
}

To understand how Templates are loaded and overridden, please check out the Template Cascade.

Post Archive Templates

They are dynamically loaded for a valid Post Type, followed by pg in the second-level, and a number in the third-level

domain.com/blog/pg/100/
domain.com/writing/pg/19/

By default the Post Type blog is enabled to have an Archive. Any other Post Types you create must have their respective Archives enabled through your config.json file. See Configuration for more details.

The General Archive Template can be found at /themes/{active-theme}/archive.ms

Specific Archive by Post Type Templates can be found at /themes/{active-theme}/archive-{post-type}.ms

If you do not include an Archive Template of any kind in your theme, the one baked into Charlie will be used. It contains the following code to model from:

{{>header}}

<body>

<h1>{{post.type}} Archive</h1>

{{#post.archive}}

{{#item}}

<article>
	<h2><a href="{{{link}}}">{{title}}</a></h2>
	<time class="article-date">{{date}}</time>

	<p>{{summary}}</p>

</article>

{{/item}}

{{#post.pagination}}
<nav>
<ul>
{{#item}}
    <li>{{#link}}<a href="{{link}}">{{/link}}{{num}}{{#link}}</a>{{/link}}</li>
{{/item}}

</ul>
</nav>
{{/post.pagination}}

{{/post.archive}}


{{>footer}}

To understand how Templates are loaded and overridden, please check out the Template Cascade.

Partials Templates

Partials Templates can be found at /themes/{active-theme}/_partials/

They are then included in other templates with the following Tag convention:

{{>partial_name_here}}

They can be especially useful for repeating HEADER or FOOTER element areas across pages. If every page includes the same header, with the same logo, and the same menu it can be a good idea to put that into a Partial, and then include it in all your templates so you don’t repeat yourself unnecessarily.

Localized Variables

There are a few Variables available on a given Page or Post that can be called via Mustache Tags without having to first be defined in a Frontmatter block. They are usually generated dynamically under the hood.

Name Tag
content {{{content}}}
link {{{link}}}

Calling Variables

{{title}}

{{date}}

{{{content}}}

Calling Partials

{{>header}}

{{>footer}

Calling Blocks

{{block.intro_blurb}}

{{block.sponsor_me_on_patreon_message}}

Calling Loopers

{{#looper.blog}}

{{#item}}

<article>
	<h2><a href="{{{link}}}">{{title}}</a></h2>
	<time class="article-date">{{date}}</time>

	<p>{{summary}}</p>

</article>

{{/item}}

{{^item}}
	<li>
		<article>
			<h3>Nothing, Nada, Zip &hellip;</h3>
		</article>
	</li>
{{/item}}

{{/looper.blog}}

Calling Lambdas

{{#f_markdown}}   

# A Title Written In markdown

Content here is drafted in **Markdown**, but will output as rendered HTML thanks to this formating lambda block.

{{/f_markdown}}