1. Web Design
  2. WordPress
  3. WordPress Themes

Update: What’s New in Ghost Themes

Scroll to top
12 min read
This post is part of a series called Building a Ghost Theme From Scratch.
Uber Aesthetics and Responsiveness

Since our original Ghost theme creation tutorial series was published in late 2013, a lot of new changes have gone through the theming API. There are some new requirements for themes, a few things that are deprecated, and a great big stack of new helpers, contexts, templates and added features.

In this tutorial we’ll take “UberTheme”, the theme that was completed in lesson six of the series, update it to comply with current requirements, and include some of the latest additions to Ghost.

We won’t be implementing every new feature into our theme as there are too many to fit in one tutorial, however we’ll be going over many of these great new features just the same.

New Requirements:

“package.json” File

Themes now require a “package.json” file to define the name of the theme. This file can also contain the version number of the theme.

In the root folder of your UberTheme, create a file named “package.json” and add the following code inside:

1
{
2
  "name": "UberTheme",
3
  "version": "1.0.1"
4
}

At the moment themes just use these two fields, but as the Ghost ecosystem grows additional fields will be added to expose developer information, and help with upgrades and compatibility management.

More info can be found in the Ghost developer docs.

Use of the {{asset}} Helper

Whenever loading CSS, JS or images from the theme’s “assets” folder, you should now utilize the {{asset}} helper. This helps with caching, ensuring correct loading paths, and making sure themes are uniformly structured so people can count on finding an appropriately used “assets” folder in any theme.

Open up UberTheme’s “default.hbs” file for editing and locate lines 12 to 14:

1
    <link rel="stylesheet" type="text/css" href="/assets/css/style.css" />
2
    {{! Scripts }}
3
    <script type=’text/javascript’ src=’/assets/js/all.min.js’></script>

Edit them to use the {{asset}} helper as follows:

1
    <link rel="stylesheet" type="text/css" href="{{asset "css/style.css"}}" />
2
    {{! Scripts }}
3
    <script type=’text/javascript’ src=’{{asset "js/all.min.js"}}’></script>

Read more in the Ghost dev docs.

Deprecated

We didn’t actually use any of the following in UberTheme so you won’t need to make any edits to the theme due to deprecation. However, in any of your other Ghost theme projects, please ensure you’re no longer using these features:

{{pageUrl}} Helper

This helper used to be something that could be utilized in pagination templates. Now, use {{page_url}} instead.

{{author.email}}

This helper is removed and now only outputs an empty string. Double check your author sections and make sure it’s not used.

Classes archive-template and page

These classes used to be output if using the {{body_class}} helper, but are no longer in place.

On Pages, post-template Class

The post-template class used to be output via the {{body_class}} helper on pages, but now only appears on posts.

New Contexts and Templates

Ghost has a number of “contexts” you might find yourself in as you navigate around a blog. For example, when reading a single post you’re in the “post” context. There are now several newly added contexts that display various types of content. Below, we’re going to cover the new “author”, “page”, “tag” and “home” contexts.

As well as these new contexts there are also several new templates you can add to your theme for finer levels of control over presentation. Note that if you add new templates to your theme, you will need to restart Ghost in order for them to be picked up by the system and become operational.

Static Pages / Page Context & Custom Page Templates

Ghost now supports static pages as well as posts, making it perfect in many ways for building a typical five page small business site. To create a static page, first add a regular post then click the little gear icon in the bottom right corner of the editing interface. Then check the box in the settings sidebar labeled Turn this post into a static page.

Add a “page.hbs” template to your theme to control static page styling, or leave it to fall back on using the “post.hbs” template.

In UberTheme, duplicate the existing “post.hbs” template and rename it to “page.hbs”. We’re going to remove the markup from this template that pages don’t really need, i.e. the date posted, the tags, the sharing bar, the author info and the pagination.

Locate the <time> element on line 7 and delete it:

1
<time class="date_uber" datetime="{{date format="YYYY-MM-DD"}}" itemprop="datePublished">{{date format=’dddd DD MMM YYYY’}}</time>

Now delete all the way from line 12:

1
{{#if tags}}
2
<div class="posttags_uber">

...down to line 38, right before the closing </article> tag:

1
    	</footer>
2
		{{/if}}

Then also delete from what is now line 14, to line 18:

1
{{#if pagination}}
2
<div class="pagination_uber">
3
{{{pagination}}}
4
</div>
5
{{/if}}

Your pages should now appear with just the page title and content:

Templates for specific pages can also be created with the file naming syntax “page-{{slug}}.hbs”, e.g. “page-contact-us.hbs”.

Read more in the Ghost developer docs.

Author Page/Context & Custom Author Template

Now that Ghost supports multiple users, it’s possible to see a list of all the posts that a particular author has written. In order to provide easy access to these lists of author posts, you’ll need to add author attribution into your theme’s post display.

First, we’ll add an author attribution to UberTheme by editing the “index.hbs” file and adding the following code just before the {{content}} tag:

1
<p class="author">Written by {{author}}</p>

You’ll also want to make the same addition in the “post.hbs” file.

From your theme project’s “LESS” folder, also edit the “layout.less” file and add this styling, to italicize the author text:

1
.author {
2
    font-style: italic;
3
}

You should now have an author attribution at the top of your posts, like this:

You’ll notice that the author name is automatically linked; that link goes to a display of all the posts written by the author in question. By default, this list of author posts uses the “index.hbs” template, but you can also customize the presentation with a template named “author.hbs”.

For author specific templates use the file naming syntax “author-{{slug}}.hbs”, e.g. “author-kezz.hbs”.

Again, more can be found on this in the Ghost developer docs.

Tag Pages / Tag Context & Custom Tag Templates

When using the {{tags}} helper to show tags associated with posts, each tag will now link to a page showing all posts bearing the same tag.

Create a “tag.hbs” template file if you want to customize your theme’s tag page display, or alternatively leave it to fall back to the “index.hbs” file.

To add a tag page to UberTheme, duplicate the “index.hbs” template and rename it to “tag.hbs”. Directly after the opening <main> tag add this code:

1
{{#tag}}
2
<div class="article_uber tag_heading">
3
<p>Posts Tagged: {{name}}</p>
4
</div>
5
{{/tag}}

This will add a header to your tag listing pages showing the name of the current tag.

In your “layout.less” file, after the .article_uber selector style, add this code:

1
.tag_heading {
2
    font-size: 2rem;
3
	padding: 0 0 2rem 0;
4
	text-align: center;
5
	margin-bottom: 0.25rem;
6
}

When you go to a tag listing page you should now have a heading section for it like this:

To create different templates for specific tags, use the file naming syntax “tag-{{slug}}.hbs”. This can be great for things like creating image galleries out of posts tagged “gallery”, for example, using a template named “tag-gallery.hbs”.

Home Context / Home Template

You may wish to have a different template for your home page than you do for subsequent lists of posts as people page through. For example, you may have a large cover image or a slideshow on your homepage that you don’t want visitors to have to scroll past again on the next page of posts.

To customize your home page display, create a template named "home.hbs".

Read more in the Ghost developer docs.

Custom Error Pages

If you’d like to control the exact presentation of error pages, now you can by creating a template named “error.hbs”.

Read more in the (can you guess?) Ghost developer docs!

New Helpers

Ghost has introduced several new helpers; kind of template tags which help you output certain types of content in your theme.

{{navigation}} Helper

It’s now possible to create basic navigation menus in Ghost, by going to Settings > Navigation in the admin area.

To make a nav menu appear in your UberTheme, open up the “header.hbs” file from the “partials” folder and add this code before the last closing div tag:

1
<nav>{{navigation}}</nav>

From the project’s “LESS” folder, open up “layout.less” and locate the .header_uber class. In it, on line 33, change the padding-bottom value from:

1
padding-bottom: 3 * @golden + 0em;

...to:

1
padding-bottom: 1.5 * @golden + 0em;

Then add the following code to style your new navigation menu:

1
ul.nav {
2
    list-style-type: none;
3
	margin-top: 1.5 * @golden + 0em;
4
	padding: 0;
5
	display: flex;
6
	justify-content: center;
7
	border-top: 0.0625rem solid lighten(@color_03, 33%);
8
	border-bottom: 0.0625rem solid lighten(@color_03, 33%);
9
	background-color: lighten(@color_03, 42%);
10
	li {
11
		margin: 0 0.25em;
12
		padding: 0.75em 1em;
13
		a {
14
			text-decoration: none;
15
		}
16
	}
17
}

Note: We’re using flexbox here for quick and easy menu implementation, but if you need to support legacy browsers you may wish to use a different approach.

Your theme should now have a navigation menu that looks like this:

Read more on navigation in the.. you know.

{{image}} Helper

Ghost now provides the ability to add a featured image to any post. To add an image, click the little gear icon at the bottom right of the post editing interface, then click the Add post image square at the top of the sidebar that pops out. Alternatively, drag and drop an image onto it.

To output the post’s image use the {{image}} helper. In UberTheme, open up the “index.hbs” file and locate the {{content}} tag on line 12:

1
<div class="postcontent_uber" itemprop="articleBody">
2
{{content}}
3
</div>

Directly above it, add an image element using the {{image}} helper in the src attribute. We’ll also use the post’s title in the alt attribute, and wrap it with an {{#if image}}...{{/if}} check to make sure there’s an image to show:

1
<div class="postcontent_uber" itemprop="articleBody">
2
{{#if image}}
3
<img src="{{image}}" alt="{{title}}">
4
{{/if}}
5
{{content}}
6
</div>

You should now be able to see any added post image right below the post title in your theme, like so:

Go on, docs.

{{#has}} Helper

The new {{#has}} helper lets you check if a post has a certain author as its writer, and / or has certain tags associated with it. This allows you to do things like creating different types of presentation for different authors, or in the case of tags, setting up different types of posts similar to Tumblr themes or WordPress post formats.

For example, you could have all posts tagged “photo” presented with a special photo layout, all posts tagged “video” presented in their own way, and other posts falling back to the default markup:

1
{{#has tag="photo"}}
2
    Special photo post presentation here
3
{{else}}
4
    {{#has tag="video"}}
5
        Special video post presentation here
6
    {{else}}
7
        Fall back to default presentation
8
    {{/has}}
9
{{/has}}

Docs.

{{#is}} Helper

So far we’ve gone through many of the new “contexts” within a Ghost site, such as “post”, “author”, “page”, “tag” and “home”. The {{#is}} helper gives you a way to control output in a template depending on which context the template is being used in.

For example, instead of creating a different “tag.hbs” template as we did above, you might add the following to your “index.hbs” file instead:

1
{{#is "tag"}}
2
    {{#tag}}
3
    <div class="article_uber tag_heading">
4
    <p>Posts Tagged: {{name}}</p>
5
    </div>
6
    {{/tag}}
7
{{/is}}

The {{#is "tag"}} line checks to see if the current context is “tag”, i.e. that the viewer is looking at a list of posts under a certain tag, and only then will it output the tag heading.

Read more.

{{#prev_post}} and {{#next_post}} Helpers

If you would like, you can now add a Next Post and a Previous Post link to allow readers to go straight from reading one post to another. These links should be added to the “post.hbs” template.

An example of how these links might be implemented, (from the Ghost docs page), is as follows:

1
{{#post}}
2
  <h2>{{title}}</h2>
3
  <div class="{{post_class}}">
4
    {{content}}
5
  </div>
6
7
  {{#prev_post}}
8
    <a href="{{url}}">{{title}}</a>
9
  {{/prev_post}}
10
11
  {{#next_post}}
12
    <a href="{{url}}">{{title}}</a>
13
  {{/next_post}}
14
{{/post}}

Overriding Templates

All the templates we’ve covered so far correspond with certain contexts, however there are some that can be used to control the output of certain helpers, e.g. {{navigation}} and {{pagination}}. By default Ghost handles the output of these helpers automatically, but you have the option of defining your own output within your theme.

Navigation Template

The default markup output by the {{navigation}} helper is:

1
<ul class="nav">
2
    {{#foreach navigation}}
3
    <li class="nav-{{slug}}{{#if current}} nav-current{{/if}}" role="presentation"><a href="{{url absolute="true"}}">{{label}}</a></li>
4
    {{/foreach}}
5
</ul>

To use your own navigation markup instead, create a file named “navigation.hbs” and place it in the partials directory of your theme.

Read more in the docs.

Pagination Template

The ability to create a custom template for the {{pagination}} helper isn’t actually new, but it’s something we didn’t cover previously in the series and is thus worth mentioning here. The default {{pagination}} code in Ghost is:

1
<nav class="pagination" role="navigation">
2
    {{#if prev}}
3
        <a class="newer-posts" href="{{page_url prev}}">&larr; Newer Posts</a>
4
    {{/if}}
5
    <span class="page-number">Page {{page}} of {{pages}}</span>
6
    {{#if next}}
7
        <a class="older-posts" href="{{page_url next}}">Older Posts &rarr;</a>
8
    {{/if}}
9
</nav>

Override this code with your own by creating a template named “pagination.hbs” in your theme’s “partials" folder.

More here in the docs.

Extra Features

As well as new contexts, templates and helpers, Ghost also has a few more things added into the mix.

Featured Posts

If you would like to mark a specific post as “Featured”, there are now two ways in the admin interface.

From the admin space that lists all your posts, click the little star in the top left right corner of the post preview window.

From inside the post editor, click the little gear icon at the bottom right of the screen, then check the box labeled Feature this post.

In your theme, if you would like to use different markup for featured posts, check if a post is featured with {{#if featured}}

1
{{#foreach posts}}
2
    {{#if featured}}
3
        <!-- Featured post markup here -->
4
    {{else}}
5
        <!-- Regular post markup here -->
6
    {{/if}}
7
{{/foreach}}

Featured posts also bear the class featured allowing you to target them for different styling in your CSS. In order for this class to be output, include the {{post_class}} helper on your posts. 

For example in UberTheme’s “index.hbs”, “post.hbs” and “page.hbs” files change this line:

1
<article class="article_uber" role="article" itemscope itemtype="http://schema.org/Article">

...to:

1
<article class="article_uber {{post_class}}" role="article" itemscope itemtype="http://schema.org/Article">

By default, featured posts are not positioned above other posts, they are in their regular position based on when they were published. However, if you would like to have featured posts appear first, you’ll need two post loops: one for featured posts and one for regular posts.

1
{{#foreach posts}}
2
    {{#if featured}}
3
	{{!-- Display featured posts here --}}
4
	{{/if}}
5
{{/foreach}}
6
7
{{#foreach posts}}
8
	{{#unless featured}}
9
	{{!-- Display regular posts here --}}
10
	{{/unless}}
11
{{/foreach}}

Everybody sing along now: read more in the docs.

Custom Favicons

To set a custom favicon, place your “favicon.ico” file in the “assets” folder and load it into the <head> section of your theme with

1
{{asset "/favicon.ico"}}

Read more on Wikipedia (kidding, try the Ghost docs).

Wrapping Up

That’s a whole lot of new power added into Ghost theme development, with a plethora of new opportunities for creative theme development!

To summarize, we have:

  • “package.json” file and {{asset}} helper use now required
  • Navigation added, with the ability to customize its HTML output
  • Featured images added
  • New helpers to allowing for many more options in markup
  • Static pages and custom templates for them
  • Tag pages and custom templates for them
  • Author pages and custom templates for them
  • Home page template
  • Custom error template
  • Featured posts
  • Customizable favicons

Even with everything we’ve covered here, there are still more new helpers and features available in Ghost, as well as more detail on all the above, so be sure to have a good read at themes.ghost.org to get all the ins and outs.

Attached to this tutorial you’ll find a source file download where you can get the updated theme, as well as the edited “layout.less” file. Use UberTheme as your testing playground to familiarize yourself with everything new in Ghost, then get out there and make some awesome themes!

Envato Market

Don’t forget to check out the Ghost category on Envato Market!

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.