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.

I've also used these same instructions to modify the Lyra theme, which is the same as Ghost but with memberships.

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 was "hacky", but it caused me more pain than I'm willing to put up with.

So follow these steps on the Ghost website to download ghost onto your computer and run it.

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

  • Optional — go into root mode with sudo -i. In Mac OS X, you have to do sudo with everything anyway and it gets tedious forgetting.
  • 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 -R 766 *.hbs and *.css in the relevant directories in the Casper theme folder.
  • Go back to the root folder for your ghost install. Run a development server with sudo ghost start -D, and you can now access your theme.

Note on node versionMac OS X tends to have too high a node version. You need to use node 8 or 10, but Mac OS X has node 11. Use the command nvm use 10 to use version 10.x.

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, Lyra or whatever).

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": "https://hooshmand.net",
    "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.

This card 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 post-card-reversed.hbs file in an editor like Brackets.
  3. Find the part surrounded by the {{#if feature_image}} tag, and move it to the bottom, swapping its position with the <div class="post-card-content"> tag.
  4. Delete everything between the <footer> tags.

Your overall structure will now be:

<article>
  <div class="post-card-content">
  ... This is where the "About" text goes ...
  </div>
  {{#if feature_image}}
  ... this is where a picture of you goes ...
  {{/if}}
</article>

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

Next, you modify your front page. Open up index.hbs.

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}}
                    {{> "post-card-reversed"}}
                {{/post}}
            {{/get}}
		</div>
    </div>
</section>

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 of my modified Ghost Casper theme.

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>

    <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>
                    </button>
                </div>
                <div class="message-success">
                    <strong>Great!</strong> Check your inbox and click the link to confirm your subscription.
                </div>
                <div class="message-error">
                    Please enter a valid email address!
                </div>
            </form>
        </div>
    </div>
{{/if}}

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="https://linkedin.com/company/hooshmanddotnet">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.

LinkedIn:

<svg xmlns="http://www.w3.org/2000/svg" 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>

Instagram:

<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.

Do this by adding the line

<a class="social-link social-link-tw" href="https://linkedin.com/company/hooshmanddotnet" title="LinkedIn" target="_blank" rel="noopener">{{> "icons/linkedin"}}</a>

And it should look like the following:

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

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}}
    ...
    {{/if}}
{{/has}}

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 make sure that featured posts come first, you modify the routes.yaml file in your Ghost installation. This isn't part of your theme — in fact, it remains static when you change themes.

You modify the routes.yaml file under Labs, then Beta features (though it's an old feature... not sure why it's still 'beta').

Ghost 3 feature for routes.yaml
Where to modify routes.yaml

This is the standard code for routes.yaml:

routes:

collections:
  /:
    permalink: /{slug}/
    template: index

taxonomies:
  tag: /tag/{slug}/
  author: /author/{slug}/

One important point before you change much in the routes file: spacing is important! Be careful with your changes or you'll break it.

The only thing I added was the line for ordering, requesting to order by featured fist, then date.

This is what I changed it to:

routes:

collections:
  /:
    permalink: /{slug}/
    template: index
    order: featured desc, published_at desc

taxonomies:
  tag: /tag/{slug}/
  author: /author/{slug}/

Then I just uploaded that file back to the same place (this is independent of the theme).

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-modified.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

Again, make sure to exclude the node_modules folder — it's pretty big.