The home page for my site, based on modified Ghost 3.0 theme casper
The home page for my site, built on Ghost 3.0

This is an updated post to my old one, "The First Five Things to Modify in Ghost 2.0's Theme Casper". Some customisations were no longer necessary, because of updates to Ghost's theme to make it more "Medium"-like (Medium looks amazing and many try to copy it).

Since Ghost 3.0 also evolved "subscribers" into "members" with new features, I've made some other customisations to integrate that into the theme.

Set up your development environment

I used to modify my theme directly on the server, but that's a bad idea. It's hard to modify CSS files, and easy to crash the site (which resulted in lots of downtime).

Yes, it's "hacky", but it caused me more pain than I'm willing to put up with~

So follow these steps:

  • Download ghost onto your computer and run it.

In your theme's directory (./current/content/themes/casper) run the following:

  • sudo yarn install and sudo yarn dev. Now you can modify your theme files (of any kind) and as soon as you do, your theme will be rebuilt and you can refresh and see the changes.
  • Make sure you can edit all your .css and .hbs files, using sudo chmod +766 *.hbs and *.css in the relevant directories in the Casper theme folder.
  • Run a development server with sudo ghost start -D, and you can now access your theme.
  • Go into root mode with sudo -i. You have to do sudo with everything anyway and it gets tedious forgetting.

Also, you need an editor. VSCode is popular, but Brackets is the one I normally use (it's faster to load).

Modify package.json so it's your own file

You can't upload a theme when it has the same package description as the current theme (Casper).

Open up package.json in your home directory and make changes to the first four lines, something like this:

    "name": "casper-dana",
    "description": "A modified version of Ghost 3.1's Casper theme",
    "demo": "",
    "version": "1.0",
Modifications to package.json

Modifying the site title and description

In a previous iteration, I wanted to centre the site description with text-align:centre;. Now, I hide it. (I want the description in there for SEO purposes... which hopefully works, but I don't want those keywords cluttering up the main page.)

I use visibility:hidden; to not mess with the layout of the page.

In screen.css, find .site-description.

.site-description {
    visibility: hidden; /*Dana*/
    z-index: 10;
    margin: 0;
    padding: 5px 0;
    font-size: 2.1rem;
    line-height: 1.4em;
    font-weight: 400;
    opacity: 0.8;

Add a sticky "About" section to the front page

I like to have a sticky feature post that's my "about" page. It's commonly done on web pages that are about a person. You have to decide if you want to believe what the hell I have to say!

First, I made a new .hbs template for post-card-reversed, which I'll use in the template. It is the same as a post-card, but it swaps the image and the text.

To do this:

  1. In ./partials, make a copy of post-card.hbs to post-card-reversed.hbs.
  2. Open the new file in an editor like Brackets.
  3. Find the part surrounded by the {{if}} tag, and move it to the top, swapping its position with the main <div> tag.
  4. Delete everything between the <footer> tags.

With that done, you can now use post-card-reversed as a template.

Right underneath the </header> tag, I added the code:

{{!-- Dana's about page, sticky post at top --}}
<section class="outer">
    <div class="inner">
		<div style="margin-top:30px;">
            {{#get "pages" slug="about" as |post|}}
                    {{> "post-card-reversed"}}

This gets you your sticky about!

Modifying Ghost 3's Casper theme to get a sticky "About" section.
My sticky "About" section on my main page.

Add a sign-up form to the front page

Since Ghost 3.0+ introduced a "Members" feature, I had to make some more customisations to make this work.

Firstly, I don't intend (for now... probably forever) to charge for memberships on this site. I just want to give people the opportunity to sign up for email updates.

It took a bit of playing around, but I copied and modified code from default.hbs until this worked. I pasted this directly below the "About" section above.

{{#if @labs.members}}
    <div class="subscribe-success-message">
        <a class="subscribe-close" href="javascript:;"></a>
        You've successfully subscribed to {{@site.title}}!

    <div id="subscribe" style="padding: 0 !important;">
        <div class="subscribe-form" style="padding:2vw !important;">
            <h1 class="subscribe-overlay-title">Subscribe to {{@site.title}}</h1>
            <p class="subscribe-overlay-description">Stay up to date! Get all the latest & greatest posts delivered straight to your inbox</p>
            <form data-members-form="subscribe">
                <div class="form-group">
                    <input class="subscribe-email" data-members-email placeholder="[email protected]" autocomplete="false" />
                    <button class="button primary" type="submit">
                        <span class="button-content">Subscribe</span>
                        <span class="button-loader">{{> "icons/loader"}}</span>
                <div class="message-success">
                    <strong>Great!</strong> Check your inbox and click the link to confirm your subscription.
                <div class="message-error">
                    Please enter a valid email address!

Add in customised socials (Instagram, LinkedIn)

You might want to add Instagram, or LinkedIn. I used to have both; right now I just use LI as it's more relevant for me.

For the site nav, in default.hbs, find the site-footer-nav section and add in a line like this:

<a href="">LinkedIn</a>

You also need to add in icon .svg files for LinkedIn and/or Instagram. I poked around the internet until I found the right ones. Here they are. You save these to files in ./partials/icons.


<svg xmlns="" x="0px" y="0px"
width="26" height="26"
viewBox="0 0 192 192"
style=" fill:#000000;"><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M0,192v-192h192v192z" fill="none"></path><g fill="#ffffff"><g id="surface1"><path d="M156,0h-120c-19.875,0 -36,16.125 -36,36v120c0,19.875 16.125,36 36,36h120c19.875,0 36,-16.125 36,-36v-120c0,-19.875 -16.125,-36 -36,-36zM59.36539,162.98077h-29.82693l-0.17307,-89.30769h29.82692zM43.70192,61.99038h-0.17308c-9.75,0 -16.03846,-6.72115 -16.03846,-15.08653c0,-8.56731 6.49039,-15.0577 16.41347,-15.0577c9.92308,0 16.00961,6.49038 16.21153,15.0577c0,8.36538 -6.31731,15.08653 -16.41346,15.08653zM162.77885,162.98077h-30.08654v-48.51923c0,-11.74039 -3.11538,-19.73077 -13.61538,-19.73077c-8.01923,0 -12.34615,5.39423 -14.42308,10.61538c-0.77885,1.875 -0.98077,4.44231 -0.98077,7.06731v50.56731h-30.23077l-0.17308,-89.30769h30.23077l0.17308,12.60577c3.86538,-5.97116 10.29808,-14.42308 25.70192,-14.42308c19.09616,0 33.37501,12.46154 33.37501,39.25961v51.86539z"></path></g></g></g></svg>


<svg viewBox="0 0 512 512"><path d="M256 109.3c47.8 0 53.4 0.2 72.3 1 17.4 0.8 26.9 3.7 33.2 6.2 8.4 3.2 14.3 7.1 20.6 13.4 6.3 6.3 10.1 12.2 13.4 20.6 2.5 6.3 5.4 15.8 6.2 33.2 0.9 18.9 1 24.5 1 72.3s-0.2 53.4-1 72.3c-0.8 17.4-3.7 26.9-6.2 33.2 -3.2 8.4-7.1 14.3-13.4 20.6 -6.3 6.3-12.2 10.1-20.6 13.4 -6.3 2.5-15.8 5.4-33.2 6.2 -18.9 0.9-24.5 1-72.3 1s-53.4-0.2-72.3-1c-17.4-0.8-26.9-3.7-33.2-6.2 -8.4-3.2-14.3-7.1-20.6-13.4 -6.3-6.3-10.1-12.2-13.4-20.6 -2.5-6.3-5.4-15.8-6.2-33.2 -0.9-18.9-1-24.5-1-72.3s0.2-53.4 1-72.3c0.8-17.4 3.7-26.9 6.2-33.2 3.2-8.4 7.1-14.3 13.4-20.6 6.3-6.3 12.2-10.1 20.6-13.4 6.3-2.5 15.8-5.4 33.2-6.2C202.6 109.5 208.2 109.3 256 109.3M256 77.1c-48.6 0-54.7 0.2-73.8 1.1 -19 0.9-32.1 3.9-43.4 8.3 -11.8 4.6-21.7 10.7-31.7 20.6 -9.9 9.9-16.1 19.9-20.6 31.7 -4.4 11.4-7.4 24.4-8.3 43.4 -0.9 19.1-1.1 25.2-1.1 73.8 0 48.6 0.2 54.7 1.1 73.8 0.9 19 3.9 32.1 8.3 43.4 4.6 11.8 10.7 21.7 20.6 31.7 9.9 9.9 19.9 16.1 31.7 20.6 11.4 4.4 24.4 7.4 43.4 8.3 19.1 0.9 25.2 1.1 73.8 1.1s54.7-0.2 73.8-1.1c19-0.9 32.1-3.9 43.4-8.3 11.8-4.6 21.7-10.7 31.7-20.6 9.9-9.9 16.1-19.9 20.6-31.7 4.4-11.4 7.4-24.4 8.3-43.4 0.9-19.1 1.1-25.2 1.1-73.8s-0.2-54.7-1.1-73.8c-0.9-19-3.9-32.1-8.3-43.4 -4.6-11.8-10.7-21.7-20.6-31.7 -9.9-9.9-19.9-16.1-31.7-20.6 -11.4-4.4-24.4-7.4-43.4-8.3C310.7 77.3 304.6 77.1 256 77.1L256 77.1z"/><path d="M256 164.1c-50.7 0-91.9 41.1-91.9 91.9s41.1 91.9 91.9 91.9 91.9-41.1 91.9-91.9S306.7 164.1 256 164.1zM256 315.6c-32.9 0-59.6-26.7-59.6-59.6s26.7-59.6 59.6-59.6 59.6 26.7 59.6 59.6S288.9 315.6 256 315.6z"/><circle cx="351.5" cy="160.5" r="21.5"/></svg>

Now in content/themes/casper/partials/site-nav.hbs add in the relevant links and icon references.

adding in the new linkedin icon into your ghost casper 3.0 theme
The new linkedin icon you've added

Don't display feature images if you don't want them

Modifying the Ghost page or post to not show a feature image, using custom tags.
My about page using Ghost - does not have a feature image, even though the page does have a feature image associated with it

This was a post I made separately here about how to show a different hero image to the feature image.

Sometimes you just don't want to show a feature image at all.

You do this by creating a custom tag (I use #nofeature) and then modifying the post.hbs and page.hbs files so it does something different when that tag exists.

Find the section that says {{#if feature_image}}, and surround it by {{#has}} tags.

It should look like this:

{{^has tag="#nofeature"}}            
	{{#if feature_image}}

Then in both your pages and posts, you can use that tag. For example, I don't have a feature image in my about page.

I write a lot of posts. Some of them I only want to be found by search engines, but some I want to be on the front page as my "branding".

To do this, you modify index.hbs so it only shows featured posts, not all posts.

This is the standard code:

{{!-- The main content area --}}
<main id="site-main" class="site-main outer">
    <div class="inner posts">
        <div class="post-feed">
            {{#foreach posts}}
                {{> "post-card"}}

Change it to this, so it's doing a query only on featured posts:

<main id="site-main" class="site-main outer">
    <div class="inner posts">
        <div class="post-feed">
			{{#get "posts" filter="featured:true" include="tags,authors"}}
            {{#foreach posts}}
                {{> "post-card"}}

Zip up your theme and upload it!

Now that your theme is working, you can zip it up and install it into your theme.

Go into the parent folder of where your theme is.

Now, using the command line zip utility you can type:

zip ./casper -r -x *node_modules*

The -r function makes sure it recurses through all the directories.

The -x function excludes the node_modules folder, which means your zip file will be tiny (you don't need those modules, they're for development only)

You can also use an archive utility like the one in Mac Os X:

Use the Archive utility to create the Ghost theme to upload
Using the archive utility to create your Ghost theme