Skarding.com

A blog in the making.

Blogging with Spacemacs and Hugo: From org note to published post in a keystroke

What better to write about as a first blog post, than how I set up the blog?

After reading Matt Might’s post on tips for low-cost academic blogging I decided go give it a go. Being a frequent user of org-mode I decided to use Spacemacs and org-mode as my writing tool. Luckily it ends up being a pretty slick process.

Setting up a sample blog

Blogging with ox-hugo combines org-mode and Hugo. This creates a low barrier to create blog posts. The entire process of how to set it up was unknown to me, so here goes a high level overview of the resources I got started with.

The following are the resources I’d recommend to get started. In the end you’ll have a sample blog hosted on Netlify, published by Hugo and updated through Emacs/Spacemacs:

  1. Install Hugo
  2. Follow the Hugo quick start. By the end of this you’ll have a sample blog locally hosted.
  3. Upload the sample Hugo blog to a Github repo. This is required for step 6.
  4. Set up ox-hugo according to their instructions. (I went for the one post per sub-tree workflow).
  5. Set up a simple org file and export it to Hugo to test if it works. I found some example org files on the ox-hugo site, at the time of this writing I cannot seem to find them again. Some other examples can be found here, here and here. This should give you a sample blog which is updated from org-mode.
  6. I chose to host on Netlify, it is easy and free. Here is a link to the host Hugo on Netlify guide. By the end of this, you should have your sample blog hosted on your service of choice.

If you’d like to have your own domain you’ll have to buy one, for which there are plenty of vendors and Netlify guides the set up with https etc.

Deploy with a keybinding from org-mode

ox-Hugo already comes built in with , e e H H as a keybinding for storing a post locally. My goal is to have a simple way to go directly from writing all the way to a published post. So here we’ll cover how to automate the publishing. We’ll want to publish with Hugo and push to our git repository with a keystroke in Spacemacs. We will achieve this in the following way:

  1. Write a simple bash script which automates the publishing and pushing for us.
  2. Call the script from a hotkey in Spacemacs.

The following script publishes the markdown files as static html and pushes all changes in the repo. Put this script in the Hugo root folder (the same place you pointed ox-hugo to).

#publish markdown to static html
hugo

# A crude git script that adds everything, commits and pushes
git add .
git add -u
git commit -m "Another blog post"
git push origin master

Add the below lisp code to your (defun dotspacemacs/user-config ().

(defun hugo-publish ()
  (interactive)
  (shell-command "path-to-script/hugo-publish.sh"))
(spacemacs/set-leader-keys-for-major-mode 'org-mode "ehp" 'hugo-publish) ;; bind to <leader> e h p

I chose to use a relative path for the shell command in the case that I accidentally execute this command from another file it is less likely to actually run the script.

Now we have set up where two commands takes us from written blog post to fully published. I plan on using the following workflow (assuming your <leader> is ,):

  1. The keybinding: , e e H H exports to Hugo and we can see how the post looks by opening a browser at http://localhost:1313/
  2. The keybinding: , e h p publishes to html and pushes all changes to GitHub where Netlify takes over and deploys the new post.

There is plenty of room for improving the automatic process:

  • The bash script writes the same commit message every time. A better solution would be to prompt the user for a commit message and pass that on to the git commit command.
  • With this solution Emacs will freeze until the script finishes. An alternative is to call the script using the ‘start-process’ command, in which case the script will be executed asynchronously.
  • A command for starting the local Hugo server if it is not already running and opening a web browser at http://localhost:1313/.

The workflow

  1. Write blogpost in an org subtree
  2. Export subtree with , e e H H
  3. Check out blog at http://localhost:1313/, read through and check that everything is good. If not, return to step 1. Iterate until satisfactory.
  4. Publish with , e h p.