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.
Try Ghost for 2 WeeksSet 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 dosudo
with everything anyway and it gets tedious forgetting. sudo yarn install
andsudo 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, usingsudo 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
version — Mac 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:
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:
- In
./partials
, make a copy ofpost-card.hbs
topost-card-reversed.hbs
. - Open the new
post-card-reversed.hbs
file in an editor like Brackets. - 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. - 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!
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:
Don't display feature images if you don't want them
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.
Change the front page so it only shows featured posts
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').
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:
Again, make sure to exclude the node_modules
folder — it's pretty big.