The Ghost Themes Developer Hub

Welcome to the Ghost Themes developer hub. You'll find comprehensive guides and documentation to help you start working with Ghost Themes as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started    


Handlebars is the templating language used by Ghost.

Handlebars provides the power necessary to let you build semantic templates effectively with no frustration.

If you're looking to get started writing your own theme, you'll probably want to get yourself familiar with handlebars syntax first. Have a read of the handlebars documentation, or checkout this tutorial from Treehouse – you can skip the first section on installation and usage (we’ve done that bit for you) and get stuck in with ‘Basic Expressions’.

Ghost also makes use of an additional library called express-hbs which adds some additional features to handlebars which Ghost makes heavy use of, such as layouts and partials.

Introduction to Handlebars

The key thing to keep in mind when wiring up your Ghost theme to output data, is that you can only output the data that you have available to you. Each template you build for a Ghost theme has specific pieces of data, depending on what the template is for (we refer to the purpose of a template as its 'context') - for example, post.hbs only has access to a single post, where as index.hbs will get a list of many posts. You can find out what data a template has access to by looking it up in the Context Table.

All the data which a template has access to is effectively a big JSON object - a set of nested properties and their values, which looks something like this for a post (full details of the data structures can be found in the 'Data' section of the docs):

  post: {
    id: "xyz",
    title: "My blog post title",
    slug: "welcome",
	  author: {
      id: "abc",
      name: "Jo Bloggs",

Handlebars gives you the ability to access and output this data in different ways, through various Handlebars expressions....

Handlebars Expressions

All of handlebars comprises expressions which are wrapped in curly braces, for example {{title}}. There are lots of variations of these expressions, and different ways they can be used. The rest of this page gives a rundown of the different types of expression. For details of helpers available in Ghost, please see the Helper Reference.

Data Expressions

E.g. {{title}}, {{name}}

The most simple thing that Handlebars can do is output a piece of data that your template has access to. If you want to output the title for a blog post, and you know that posts have a data property called title which contains the title, then in your theme you can use the expression {{title}} to output the post title.

Data expressions are how you output a variable or property directly using Handlebars.

HTML Data Expressions

E.g. {{{bio}}}

Sometimes, the data you want to output might contain HTML, E.g. the Author's bio field. By default, Handlebars will output HTML as if it is plain text. However you can tell Handlebars to render HTML properly by using triple-braces around your data property, for example {{{bio}}}.

Global Data

E.g. {{@blog.title}}

Ghost also provides access to some global data through the {{@blog}} property, for example {{@blog.title}}. Note: The @ sign is also used to provide special properties inside of block helpers.

Path Expressions

E.g. {{}}

Sometimes, the property you want to output isn't available in the current scope directly because it belongs to another object. For example if you want to output the name of the author of your post, then {{name}} won't work on its own. Instead you can use dot notation to access data via a path. For example the author's name would be: {{}}.

Handlebars allows you to do lots of different things using paths, including using ../ to traverse up the JSON object, and array indexing using syntax like .[0], check out the Handlebars documentation for more details.


E.g. {{tags prefix=(t " on ")}}

tags is the outer helper and t is the inner helper.
First the inner helper get's executed and the result from this helper get's passed into the outer helper as the value of the parameter prefix. A subexpression (in our example the t helper) is delimited by parentheses. The concept of subexpressions allows you to invoke multiple helpers in one expression. They can be useful when translating your theme.

Block Expressions (Scopes)

E.g. {{#post}}{{/post}}

Sometimes, you want to output a lot more than just one property from an object. For example if you're creating a nicely styled author block for a post, you'll want to access lots of author properties. Rather than using lots of path expressions, instead you can use a block expression to open up a particular object and access its properties directly. This is referred to as opening a 'scope'. The scope you are in is very important for knowing what data is accessible.

Block expressions have an opening and a closing tag, much like HTML: {{#author}}{{/author}}. Between these opening and closing tags, we are in the 'author' scope, so we can access the properties of the author directly. For example:

    My name is {{name}}, visit my <a href="{{website}}">Website!</a>

Block expressions vs path expressions

{{#author}}{{name}}{{/author}} does very much the same thing as {{}}. The big difference is, by using block expressions you can also access handlebars helpers for the object you are inside. E.g. an author doesn't have a url property, so {{author.url}} doesn't work, but {{#author}}{{url}}{{/author}} will.


The most common example of a block expression in Ghost is the post block expression used in post.hbs. Usually the whole template is wrapped with {{#post}}{{/post}} so that the rest of the template has direct access to post properties. We highly recommend using block expressions rather than path expressions wherever possible as this makes it easier to use the custom helpers provided by Ghost.

Block + Path Expressions

A more advanced use of block expressions would be to use a path expression to target a specific post from within the posts helper. The following example shows how to work with latest post on the homepage:

  <h3 class="first_title">{{title}}</h3>
  <div class="first_content">{{content}}</div>


E.g. {{content}}, {{url}}

The difference between helpers, and all the other expressions we've seen so far is that helpers do some work behind the scenes, rather than just outputting data. Essentially, data expressions are variables, and helpers are functions. Ghost provides a set of helpers specifically designed to make building blog themes easy. Some of the helpers are general purpose and can be used in lots of places, but many of them have a very specific job to do.

One of the most important specific helpers is the {{content}} helper. It helps output the HTML content of a post and therefore only works when inside the post scope. The {{content}} helper has attributes that you can specify to restrict how much content is output, E.g. {{content words="50"}}. Handlebars attributes are very similar to HTML attributes.

Other helpers will do different things depending on where you use them - for example the {{url}} helper will work for posts, tags and authors, and will output the correct URL for the current object. {{body_class}} will output different classes depending on the context, for example it outputs home-template on the homepage and post-template on a post page.

Date is a formatting helper. It takes a parameter as well as attributes, for example {{date published_at format="MMMM DD, YYYY"}}, where published_at is the date you want to output, and the format attribute decides how to format the date. If you don't pass in a parameter, the {{date}} helper will use the published_at property by default if it is accessible.

The Helper Reference has a full list of all the helpers available in Ghost, explains what they do, what attributes they have and where they can be used.

Block Helpers

E.g. {{#if}}{{/if}}, {{#foreach posts}}{{/foreach}}

Block helpers are very similar to block expressions. They are helpers which have a start and end tag, so they let you wrap blocks of your template. Handlebars has a number of built in block helpers, including the if helper, which lets you wrap a template block in a conditional. For example: {{#if featured}}{{/if}} lets you check if a post is featured.

Ghost has a number of additional block helpers, including {{#foreach}} which lets you iterate over a list of objects. This is particularly important on the index.hbs and other list templates as it allows you to loop through the posts with {{#foreach posts}}{{/foreach}}and output information about each one. Note the difference between the block helper {{#foreach posts}}{{/foreach}} and the block expression {{#post}}{{/post}}. The first allows you to output multiple posts, whereas the second just helps you access direct properties on one post.

Some block helpers provide access to special properties, for example inside the {{#foreach}}{{/foreach}} helper you can access the {{@first}} property.

The Helper Reference has a full list of all the block helpers available in Ghost, explains what they do, what attributes they have and where they can be used.


All block helpers support having an {{else}} block which is executed if the block helper doesn't meet certain criteria, for example if there is no post when attempting to open a {{#post}} scope, or if the tests an {{#if}} or {{#has}} helper are performing fail. It's even possible to use {{else}} with {{#foreach}}, which will be called if there are no items to loop over.

Else Chaining

Some block helpers will support else chaining, so you can have multiple checks a bit like a switch statement. {{#if}},{{#has}}and{{#is}}` all work this way, e.g.

  {{#if featured}}
    // If the post is featured
  {{else if featured_image}}
   // If the post has a featured image


As well as using else, it is also possible to swap the # in a block helper for a ^, which will negate the operation being performed. This essentially switches the opening block and the else block around. {{^if}} is the same as {{#unless}} and {{^foreach posts}}{{/foreach}} would output the template between the tags only if there were no posts to loop over.

Layout Expressions

E.g. {{!< default}}, {{{body}}}

Layouts let you define a base template which other templates can extend. The common usage of this in Ghost is to create a default.hbs layout which contains the header and footer HTML for your blog and has the {{{body}}} helper where the rest of the content should go. Every other template then starts with the expression {{!< default}} to declare that it extends the default layout. You can define multiple layouts in your Ghost theme.

More information about the default layout can be found in the layouts section of the structure guide.

Note: The layouts feature comes from express-hbs and is not part of the normal Handlebars language.

Partial Expressions

E.g. {{> loop}}

Partials allow you to create small reusable templates which you include in other template files. For example, you might create a loop.hbs partial which you use on all of the listing templates to output a short post excerpt. Partials have to live in the /partials/ directory, and are output with the {{> loop}} partial helper. The partial helper will also take a string path if you have subdirectories inside your partials directory, e.g. {{> "author/mini-bio"}}.

More information about partials can be found in the partials section of the structure guide.


E.g. {{!-- comments --}}

Handlebars also supports {{!-- comments --}}, which unlike HTML comments, won't be output in your page source, making them super useful. Handlebars comments can be multi-line the same as HTML comments