A blog about software development

Creating my first Ghost theme

The more I play around my Ghost blog, or the little there is to play with, the more exited I get. At this point I'm about to create my own Ghost theme for the hosted blog. I'm writing this article as I'm progressing with the project. So now, a glass of white wine and I'm ready for an evening with Ghost!

1. Setting up the project

Ghost has an awesome short guide on theming at their documentation page. From there you can see the simple and clean structure. They've kindly created a, again, simple bunch of helpers which you can use to hook up the data to your theme. Ghost themes require only a few little files in the package. Got to love the simplicity!

But! I'm definately not going to start building the whole theme from scratch. You can get the default theme called Casper from the downloaded platform files or from this GitHub repository. I'm basing my theme on the repository files.

2. Exploring the files

Right now I'm looking at the theme files. There seems to be four main files for the templates. I know the documentation for these files is clear on the Ghost docs page but here's a very short explanation of the templates:

  • default.hbs is the base of everything.
  • index.hbs is the front-page or the post list.
  • page.hbs is for the static pages.
  • post.hbs is for the individual post pages.

The CSS is pretty straightforward and self-explanatory. I love this line from the end of screen.css: "Do not add stuff below this point, or it will probably fuck everything up." The JavaScript portion of the theme looks to be taking care of mostly image sizes and video embeds.

3. Adding Disqus comments

Ghost doesn't have a commenting feature. This is a great design approach as there are a number good ways to implement comments like you would do on so many other websites. My favorite tool is Disqus which I'm going to add to this blog as well.

Get the code

I have an account already on Disqus. If you don't, it's only a few clicks away. To add the comments to my blog I copied the embeddable code from under Settings > Install > Universal Code.

Embed the code

Now that I have the code I opened the file post.hbs in Sublime Text 2 (you can use whichever editor you wish). Quite close to the end I found the closing tag for HTML element "footer". I placed the code between </footer> and {{/post}}.

Add the post identifier

The Disqus code doesn't have anything to specify the identifier for your post. By default, the URL is used. However, this can be troublesome when migrating from domain to another or when changing post's URL slug. I'm going to use the post's own unique identifier as the disqus_identifier. To accomplish this I added var disqus_identifier = '{{{id}}}'; just under the line /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */. This configuration variable tells Disqus to use the post's ID as the identifier. Comments are now safe from URL changes!

Half an hour and a glass of white wine later, I have a good idea about the theme file contents, the project set up, and the Disqus comments implemented to all posts. Let's keep on going...

4. Google Analytics

Now I'll get started with the analytics. Again, if you don't have an account yet on Google Analytics you should set it up before continuing with the rest of this chapter.

Set up the site and get the tracking code

I didn't have a site set up on Google Analytics yet, so I went to Admin tab from the top navigation. After that I clicked on the dropdown from the left most column. On bottom of the menu I found "Add new site" option. The site will ask you a few details and then presents you with the tracking code. Copy the code to your clipboard.

Embed the tracking code to your theme

To add the tracking code to my blog I opened the default.hbs which is the main template file. All of the different sub-pages use this template as the base. That's why this is the perfect place to rest the code. Paste the code between the <head>....</head> tags. I placed the code right below the two style sheets.

5. Static pages

Support for static pages only came around with the 0.4.0 "Aton" release. Ghost is missing the ability to list static pages via a helper on the templates. This is a drag for me as I would really want to combine my blog with just a couple of static pages. According to this thread on Ghost community shows that I'm not alone on this one. Some members of the community seem to be rather puristic about blog being a blog. However, I don't see a problem with a blog having a couple of static pages. After all, a blog is a representation of you and your thoughts. Static pages are just one piece of the puzzle. I absolutely hate the idea of having to throw my visitors across multiple websites for things I wish to share with them.


Since Ghost doesn't support a list of static pages at the moment I have to manually add them to my theme. Ghost has the main header in index.hbs. I find the header the most appropriate place to put the links to static pages in. Now, the next steps depend on whether you wish to keep the look & feel of the blog close to the original one:

  • One unified header: Move the <header>...</header> portion of the index.hbs to the default.hbs and add you links there.
  • Keep the lighter, more content oriented post pages: Separately add the links to index.hbs, post.hbs and page.hbs. This way you can keep the distinctive looks of the different type of pages. Just like the original Casper theme.

I'm going for the original look & feel as I want the static pages and post pages to be less visual and more about the content. On the index page I wish to have the original huge cover image which adds a little personal touch to the blog.

6. Upload the package to your blog

Now that I have the basics of my new theme ready I need to upload it to my blog to see if everything is working as I imagined. But first, I need to make a package out of it. I'll start by opening a file called package.json which is a tiny configuration file for my theme package. I'll set the name to Innovaniac and the version to 0.1.0.

Last step to create the theme package is to simply compress all the theme files into a ZIP-folder. Make sure all the files are in their original places. Otherwise there might be issues later on.

Upload the package

I have a hosted blog. To add a new theme or to update an existing one I need to log in to the blog management panel. To upload the theme I simply select the ZIP package in the file input and hit submit. Refreshing my blog shows that the upgrade was a success! I can see the comments on posts and Google Analytics is showing my visits.

From now on...

The rest is basically UI work. I'm going to spare you from the details. Overall it took a little over an hour to go through all the steps and write the article. Again, got to love the simplicity! Let me know in the comments about your Ghost blogs and the themes you've created. ;)

Tomi Hiltunen

Senior Full-Stack Developer @ Hubchat

Helsinki, Finland