In the past, while I was in the process of teaching myself to code, I spent some time focusing on Wordpress, building custom themes and plugins for clients. I had my my own website in Wordpress as well - it made sense at the time.

At one point, I moved on from Wordpress to other things, and eventually stopped freelancing and started a full-time job as a developer. πŸ‘©β€πŸ’»

I still had the old Wordpress website that I hadn't touched for a long time. It was marketing-oriented - not very personal, but okay at attracting new clients.

I was not actively looking for clients anymore, and never liked the marketing part. I wanted a personal website ✨just for fun✨ where I could experiment with silly ideas and write about my travels, work and life.

I wanted to write the frontend myself and connect that to a simple CMS for the blog.

I also wanted the CMS to be fast and easy to use. I didn't need any features other than writing and publishing blog posts.

Why Ghost

Based on the above criteria, Ghost was the best choice.

It's a headless CMS that comes with no frontend. The frontend can be written from scratch, or using an existing theme as a base.

It uses Node.js, which makes it a lot faster than Wordpress.

It's also beautifully designed and easy to use as a CMS.

In the end, it was a good choice - I'm still using it years later an I'm very happy with it ☺️✨

Setting up a local dev environment

As mentioned in the previous post, Ghost is very developer-friendly, so setting it up locally was very easy. I just followed the instructions on the Ghost Github repo - they are very straightforward.

I used Casper - the default Ghost theme - to build my own custom there. I didn't want to start from scratch, as it was my first time making a Ghost theme.

Casper is built with vanilla JS and HTML using Handlebars for templating. That makes it very easy to get content from the CMS. For example, showing the titles of the 3 latest blog posts looks like this.

{{#foreach posts limit="3"}} {{title}} {{/foreach}}

I kept some design elements from my old website but kept everything a lot simpler and cleaner this time. For the blog part I mostly kept Casper's beautiful design.

πŸŽ’ Travel plans

I really liked the idea of having my travel plans easily accessible on my website (inspired by whereisfelix.today). After playing around with the idea, I decided to make a simple box that shows my current city, my next city, and how long I'm staying.

I didn't want to over-engineer this - so I used a Google sheet for the data. You can get JSON from a public Google sheet and basically use it as a database like this:

https://spreadsheets.google.com/feeds/list/YOUR_GOOGLE_SHEET_ID/od6/public/values?alt=json

Using $.getJSON with this URL gives you the entire sheet (it has to be public and published to the web first).

I created a sheet with 3 columns: City, To (date) and From (date). When I book a new trip, I would just add a row on the top, pushing all the other trips down.

Then I wrote some JS that goes through the sheet data and finds the city I'm currently in, my next city, and the amount of days between them - then fills the box with that info.

πŸ“ Map with pins

I'm kinda obsessed with maps. I have hundreds (if not thousands) of markers saved on my Google maps, organised in various lists.

I wanted to find a fun way to display this on my website. Maybe not show all of the markers (there's way too many!), but a few favourite ones.

So I added a Google Map to my site using their API. Then I loaded some markers from a JSON file with coordinates for each marker.

That worked, but I didn't really like the way it looked. Also, the API key was on the frontend and I didn't know how to fix that without hacking Ghost. So I decided to look for another solution.

While doing research, I looked at a "visited countries" plugin for Wordpress, and saw that they were using a vector map. I decided to try that approach. A quick Google search brought me to Mapael.js - a plugin that lets you add stuff to a map using coordinates.

I added Mapael to my site and used the world map that comes with it. I took the coordinates JSON that I had already made for the Google Map, and modified it a bit to work with Mapael. Now I had a nice vector map with labeled pins on it ✨

I also wanted to show a tooltip for each pin with text, links, and maybe an image. The Mapael pin labels were kinda useless, since they couldn't be clicked, and would not render the HTML. So I used Tippy.js instead.

Tippy lets you add tooltips on any element with a Β data-tippy prop. So I wrote some code that goes through the list of map markers and adds data-tippy to each one (getting the content for it from a separate JS object, where I had manually listed all the titles, links and images).

πŸ“· Instagram

Finally, I added a feed for my two instagram accounts on the bottom of the page with Instafeed. It just shows the last 5 images from each account.

Deploying to Digital Ocean

I made a new droplet in Digital Ocean and with a one-click Ghost install.

Then I just had to ssh into my droplet and upload my theme, and the site was live πŸš€

(Yes I was deploying this manually, without going though Github or anything like that πŸ€·β€β™€οΈ)

Setting up an alias for easy deployment

Finally, I added the following alias:

alias deploy-ghost='rsync -avz --exclude "node_modules" -e "ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa" --progress ~/Desktop/ghost/content/themes/polina root@(my.site.ip):/var/www/ghost/content/themes/'

Now I all I need to do is type deploy-ghost in the terminal to push all changes.

I hope this post was helpful for anyone looking to move to Ghost! You can also read how I later upgraded my website to headless Ghost with Gatsby frontend ✨