We've talked about Ghost several times on this blog.

Most notably, we reviewed Ghost on it's release in October last year and then we said that Ghost had the best chance of success amongst many new flat-file website builders. We also covered the release of version 0.4 in January.

What started as a Kickstarter Campaign last year now has over 100,000 downloads. Far from being a complete blogging software as showcased on Kickstarter, its progress nonetheless has been steady, with each version getting new features and performance optimization.

In this tutorial, I'll give you an introduction to Ghost themes.

The basics of a Ghost theme

Handlebar.js is the templating used by Ghost along with an additional library called Express-hbs.

Not having any previous experience in these languages and libraries should not affect your decision to learn theme development for Ghost because creating a theme for Ghost is as simple as creating a HTML template. In fact, if you have ever created a WordPress theme or Joomla theme, you would find that creating a theme for Ghost is a lot simpler.

Before we get further into understanding a Ghost theme, it should be noted that Ghost is built for blogging. Ghost is developed with a clear goal to keep presentation & functionality apart and since it’s currently in its early stages; theme developers should only create themes based on the current feature set.

The file and folder structure of a Ghost theme

Ghost themes have to be placed inside the “content/themes” folder of your Ghost installation.

However before a new theme is available for selection from the backend settings page, you have restart Ghost. The restart is required even when new files are added or existing once removed or renamed.

Here are the the file and folders inside a Ghost theme:

index.hbs: This is a required file and displays your blog’s home page. Should contain the loop to display posts.

This is a required file and displays your blog’s home page. Should contain the loop to display posts. posts.hbs: This is a required file and displays the content of an individual post.

This is a required file and displays the content of an individual post. page.hbs: This displays posts marked as static pages (a new feature version 0.4). In the absence of a page.hbs template, posts.hbs is called instead.

This displays posts marked as static pages (a new feature version 0.4). In the absence of a page.hbs template, posts.hbs is called instead. default.hbs : This can be used to abstract elements such as the sidebar that have to appear on every page.

: This can be used to abstract elements such as the sidebar that have to appear on every page. error.hbs : Similar to 404 error pages, you can create a custom template to display errors in your theme.

: Similar to 404 error pages, you can create a custom template to display errors in your theme. /assets/: Additional files such as JavaScript & CSS files can be placed anywhere, however its recommended to place them inside an “assets” folder. From that folder it's then possible to serve CSS, JS and images with Ghost's built-in caching.

Additional files such as JavaScript & CSS files can be placed anywhere, however its recommended to place them inside an “assets” folder. From that folder it's then possible to serve CSS, JS and images with Ghost's built-in caching. /partials/: Similar to defaults.hbs, you can break out common components of your theme such as the header and footer. Create individual files such as “header.hbs” and "footer.hbs" and place them inside the partials folder.

Blog details in a Ghost theme

The blog details are saved in a global data accessor {{@blog}} and can be accessed by adding the code below to the theme's template files.

{{@blog.url}} The blog's URL as specified in the config.js file.

The blog's URL as specified in the config.js file. {{@blog.title}} The blog title

The blog title {{@blog.description}} The blog's description

The blog's description {{@blog.logo}} The blog's logo

The blog's logo {{@blog.cover}} The blog's cover image

Post details in a Ghost theme

The index.hbs template file is handed an object called posts which can be used to display each post. The code below can show items from each post:

{{title}} The post title

The post title {{url}} This outputs the relative URL of a post when used with a post context. It also has the option to output an absolute URL: {{url absolute="true"}}.

This outputs the relative URL of a post when used with a post context. It also has the option to output an absolute URL: {{url absolute="true"}}. {{date}} This outputs the date an article is published. This function uses moment.js and allows options to format the date before outputting.

This outputs the date an article is published. This function uses and allows options to format the date before outputting. {{excerpt}} By default this outputs 50 words from the beginning of the post content and also strips out all HTML. You can customize the number of words used: {{excerpt characters="140"}}

By default this outputs 50 words from the beginning of the post content and also strips out all HTML. You can customize the number of words used: {{excerpt characters="140"}} {{content}} This outputs the post content. You can also use this instead of {{excerpt}} to show a certain number of words without stripping HTML: {{content words="100"}}

This outputs the post content. You can also use this instead of {{excerpt}} to show a certain number of words without stripping HTML: {{content words="100"}} {{tags}} This outputs all the tags assigned to a post. Can be further customized to display a separator between each tag and also suffix and prefix.

This outputs all the tags assigned to a post. Can be further customized to display a separator between each tag and also suffix and prefix. {{tag.name}} This outputs name of a tag on individual post page. Can also be used as {{name}} when used inside the block expressions {{#tags}} and {{/tags}}

This outputs name of a tag on individual post page. Can also be used as {{name}} when used inside the block expressions {{#tags}} and {{/tags}} {} The post authors name

The post authors name {} The Author’s bio

The Author’s bio {} The author’s email

The author’s email {} The author’s website

The author’s website {} The author’s avatar / profile image

The author’s avatar / profile image {} The author’s personal cover image

Helpers in a Ghost theme

Discussing in detail about each helper is beyond the scope of this article, however you would find below a list of helpers organized in the order of their placement in a typical theme.

{{meta_title}} Displayed in the document header. Based on the context outputs either the title of an individual post or the blog title. Similar to <?php wp_title(); ?>

{{meta_description}} Currently displays only the blog description irrespective of the context.

{{ghost_head}} Is similar to <?php wp_head(); ?>. Place just before the </head> tag, it outputs the RSS feed link and the ghost version number. As development progress its usage would be similar to its equivalent code in WordPress.

{{body_class}} Again similar to WordPress, it adds class name that can be targeted to style different pages. Currently outputs either “home-template”, “post-template” or “archive-template”. Additionally it also outputs “page” if the post is marked as a page and tag names based on the tags assigned to the page/post.

{{body}} When “default.hbs” is used to abstract common elements, the body tags help mark the position where the contents of a page such as “index.hbs” or “posts.hbs” are inserted inside “default.hbs”

{{post_class}} Useful for styling different posts.

{{pagination}} Outputs HTML consisting of links to “Older” & “Newer” posts along with the page number you are on. Can be overwritten by creating a file named “pagination.hbs” and placing it inside the “partials” folder.

{{ghost_foot}} Similar to <?php wp_footer(); ?> is placed before the body tag to output scripts. Currently outputs the jQuery file but as the software progress its usage would become similar to wp_footer in WordPress.

{{asset}} Asset helper introduced in version 0.4 helps adding caching provides a more robust way to include theme assets such as css, js and images. For e.g. to include a stylesheet located inside ‘ /assets/css/’ folder of your theme, you can use below code:

<link rel="stylesheet" type="text/css" href="/{{asset "css/style.css"}}" />

The content accessible in our theme is based on the backend settings and type of content a user is allowed to add. Knowing what these are, would allow you to use them effectively in your theme. Below is the complete list of content available and the template code used to output the data.

Some conditional statements

The Post List is a basic version of WordPress’s loop to retrieve and output posts:

{{#foreach posts}} // here we are in the context of a single post such as title, url // date & excerpt. {{/foreach}}

Here's how pagination is shown in Ghost:

{{#if prev}} <a href="/{{pageUrl prev}}">Older Posts</a> {{/if}} Page <strong>{{page}}</strong> of {{pages}} {{#if next}} <a href="/{{pageUrl next}}">Newer Posts</a> {{/if}}

Final thoughts on Ghost themes

Once you design a basic template using HTML to display a blog’s home page with paginated list of posts and another page to display the contents of a post, the next step is to only rename your HTML files to suit Ghost standards and replace static content with the handlebar expressions listed above.

Many had missed the opportunity of getting started early in WordPress development and by the time they did, its templating system was already complex. Ghost on the other hand is new and its templating system is simpler enough to understand within an hour. As the software matures and its adoption continues, getting involved early will give you an headstart.