+++
date = 2018-12-17T23:00:21Z
draft = false
slug = "moving-from-ghost-to-hugo"
image = "images/2018/12/2018-12-17_23-26-46.png"
tag = ["blogging","ghost","hugo","Markdown","asciidoc"]
categories = ["blogging","ghost","hugo","Markdown","asciidoc"]
title = "Moving from Ghost to Hugo"
+++

== Why? 

I've been blogging for quite a few years now, starting on Blogger, soon onto https://rnm1978.wordpress.com/[WordPress], and then to Ghost a couple of years ago. Blogger was fairly lame, WP yucky, but I really do like Ghost. It's simple and powerful and was _perfect_ for my needs. My needs being, an outlet for technical content that respected formatting, worked with a markup language (Markdown), and didn't _f**k things up_ in the way that WP often would in its WYSIWYG handling of content. 

I ran Ghost self-hosted on AWS EC2, and this was the start of this particular story. Whilst 20 years ago, even 10 years ago, I'd quite happily spend an evening immersed in a hack project to get something working, times are different now. With a wife and two kids—and a fair bit of travel for work—the time I have at home I don't want to be spending on _getting shit to work_. And therein lies the beauty of PaaS. Never mind cloud-bollocks or what the acronyms stand for—in essence you write your blog, and someone else worries about all the rest of it. SSL certificate expired? Not my problem. Ghost needs upgrading? Not my problem. Whereas if you self-host…_totally_ your problem. 

In addition, paying for my AWS costs out of my pocket started to grate just a little. A few bucks here and there kinda add up over the course of a couple of years. Nothing major, but enough to make me pause and look around. The final itch I had was Markdown. Now link:/categories/markdown/[I do like Markdown], but a little less than I used to—and that's because I found Asciidoc. Asciidoc finishes what Markdown starts. All the slightly limited functionality in Markdown once you get beyond `*bold*` and `_italic_`, asciidoc swoops in and gives you in spades. And as much as I liked Ghost, it doesn't support Asciidoc. 

== Enter Hugo

Hugo is one of the breed of blog platforms that works by generating static HTML, which makes it simple (fewer moving parts, no database backend, etc) and nice and fast. Because it just generates HTML you can host the contents on https://pages.github.com/[Github Pages] (bye bye AWS hosting costs), and because it is just static HTML one can worry less about falling behind in versions. After all, Github are doing the actual hosting and can worry about securing the server; my only bit is the static HTML, and who cares if it's generated by an older version of code? 

== Getting set up

To get it set up locally on your Mac: 

[source,bash]
----
brew install hugo
----

There's a ton of quickstart tutorials out there—I picked the first off Google and went with that :) 

I've got my blog source on a https://github.com/rmoff/rmoff-blog[github repo], and then the output from Hugo on another - my https://github.com/rmoff/rmoff.github.io[github pages repo]. Using https://github.com/rmoff/rmoff-blog/blob/master/deploy.sh[a script I got from somewhere] (apologies I didn't keep the source link) I can automagically build and deploy the changes made locally up to both repos, and thus publish new content.  

So far I'm doing everything in text editor (VS Code). All I've missed so far compared to Ghost is that blog tags, slugs etc are entered manually in the header of the post itself, which seems a bit tedious and error prone: 

{{< highlight toml >}}

+++
categories = ["oracle", "cdc", "debezium", "goldengate", "xstream", "logminer", "flashback", "licence", "ksql"]
date = 2018-12-12T09:49:04Z
description = ""
draft = false
image = "/images/2018/12/IMG_7464.jpg"
slug = "streaming-data-from-oracle-into-kafka-december-2018"
tag = ["oracle", "cdc", "debezium", "goldengate", "xstream", "logminer", "flashback", "licence", "ksql"]
title = "Streaming data from Oracle into Kafka (December 2018)"
+++

{{< /highlight >}}

Check out the nice https://gohugo.io/content-management/syntax-highlighting/[syntax highlighting] there - using the `highlight` https://gohugo.io/content-management/shortcodes/[shortcode]. You can use standard code markup from asciidoc but so far I've not found out how to get it to do the syntax highlighting on it too: 

[source,bash]
----
echo 'This is a bash statement in asciidoc code markup'
----

{{< highlight shell >}}
echo 'This is a bash statement in Hugo syntax highlighting markup'
{{< /highlight >}}


== Migrating from Ghost

This was pretty easy: 

1. Export from Ghost to get a json file
2. Convert it with https://github.com/jbarone/ghostToHugo
+
[source,bash]
----
./ghostToHugo -p ~/git/rmoff-blog/ --dateformat "2006-01-02 15:04:05" ~/Downloads/rmoffs-random-ramblings.ghost.2018-12-15.json
----
3. Download the `content` folder from Ghost and move the images folder to `static` in your Hugo deployment. For me this was sufficient for all the paths to match up and all existing posts to retain their images
4. Ghost uses `tag` for its tag URLs (e.g. `link:/tag/goldengate/`), whereas Hugo uses `tags`. You can change your config to match this (`tag: tags` -> `tag: tag`): 
+
[source,yaml]
----
taxonomies:
  category: categories
  tag: tag
----
+
You then need to change each article's header to use `tag` instead of `tags` - a quick `sed` will do this (another reason why markup is so powerful; you don't lose metadata and you can bulk-process files easily)
+
{{< highlight shell >}}
sed -i '.bak' 's/^tags =/tag =/g'
{{< /highlight >}}

== Themes

There's a ton of themes available; I'm using the rather nice https://story.xaprb.com[**Story**] theme from Baron Schwarz. Installing themes is a simple matter of adding it as a submodule into your existing Hugo folder

[source,bash]
----
git submodule add https://github.com/xaprb/story.git themes/story
----

and then setting the theme name in your `config.yaml` file. 

Different themes have different properties; this one reserves H1 and H2 for its own use, so you need to make sure your articles use H3 onwards. Again, easily fixed with `sed` (all mine started at H2): 
{{< highlight shell >}}
sed -i '.bak' 's/^##/###/g'
{{< /highlight >}}

If I get round to it I might try and customise it myself to make the body just a bit wider; a lot of my articles include code samples and it'd be useful to see a bit more of them. 

You can configure the top menu items using the `menu` configuration in `config.yaml` (mine is public https://github.com/rmoff/rmoff-blog/blob/master/config.yaml#L39[here])

== Wanna See Under the Covers?

If you want to see how this is all set up, the code is public. 

* https://raw.githubusercontent.com/rmoff/rmoff-blog/master/content/post/moving-my-blog-to-hugo.adoc[This article's source (asciidoc)]
* https://github.com/rmoff/rmoff-blog/blob/master/config.yaml[Hugo config]
* https://github.com/rmoff/rmoff-blog/blob/master/deploy.sh[Deploy script]
* https://github.com/rmoff/rmoff-blog/[Blog repo]

== GitHub Pages

Setting this up is as simple as pushing code to a github repo. It even provides SSL certs, that you don't have to manually renew 👌

== Comments

I used Disqus for comments on my Ghost blog, but got very few really, and those I did half were asking for help and would be better posted on StackOverflow or elsewhere. I link:/2018/12/12/streaming-data-from-oracle-into-kafka-december-2018/[wrote an article recently] in which I invited comments and discussion in the comments facility; I got zero there, and a good half dozen on Twitter, LinkedIn, and email. 

My conclusion is that comments are not really that useful nowadays; the social networks have pretty much replaced them—and so I've not bothered to migrate them over here. I _think_ that they do actually work out of the box with Hugo and Disqus, but the theme I'm using doesn't support them and that doesn't bother me. It just makes for a cleaner site. 
