It has been long since I have published the previous post to this blog. I switched from Spacemacs to Emacs (with my own configuration) more than one month ago, and also made some changes to the theme for this blog, but didn't finish configuration for actual writing. I didn't like my previous configuration for Hugo, because I found it unnecessarily complicated after I learned a little more about Emacs.

I could finally simplify my configuration for Hugo, so I will describe the new recipe in this post. The previous configuration is totally deprecated.

Writing a blog is crucial, because it is crucial to share what you learn. My Emacs configuration is still on the way, because Emacs configuration will never be finished, but a blog setup should be done as soon as possible.

Because the blog is powered by Hugo, it doesn't depend on Emacs to publish posts. All I have to do is to implement a workflow with Emacs. It is much more simplified now.

Compilation with Projectile

Hugo has a built-in server for previewing drafts. It watches sources files in your project directory and automatically rebuilds pages. All modern front-end frameworks seem to have one, like Hot Module Replacement of Webpack, but the server of Hugo is blazingly fast, because it is written Go.

Previously, I followed this recipe to run the preview server as an asynchronous process in the background. An alternative solution is to run the server as a compiler. Projectile package allows you to register a per-project compilation command, so you can use this feature to run Hugo when you are are working on your blog.

To configure a per-project compilation command, set projectile-project-compilation-cmd variable. It is suggested that you should save the variable in .dir-locals.el in the project repository. .dir-locals.el for a Hugo project should be as follows:

((nil . ((projectile-project-compilation-cmd
          . "hugo server --buildDrafts --watch --disableFastRender"))))

The server can be started by projectile-compile-project command. To stop the server, use kill-compilation command. The result is the same as before, but I didn't have to write any code except for the variable setting, and this technique is universally applicable to other projects.

A header template

A Hugo post requires a file header. It can be generated by hugo command, but a simpler solution is to set up a snippet. I am currently trying to use yankpad (which is based on Org-Mode and yasnippet) as a snippet manager for Emacs, so I created hugo category in the snippets file and added the following snippet:

title: $1
categories: []
date: `(format-time-string "%FT%H:%M:%S%:z")`
draft: true
tags: []


It will be a good idea to specify yankpad-category in .dir-locals.el as follows:

((nil . ((projectile-project-compilation-cmd
          . "hugo server --buildDrafts --watch --disableFastRender")))
   (yankpad-category . hugo))))

Using Org-Mode for writing posts

Hugo has a built-in support for Org-Mode. You can write posts directly in Org-Mode, and Hugo can convert them into web pages without any external program. It uses goorgeous Org parser written in Go. I am using Org as the default format for plain text in Emacs, so it is convenient to be able to paste directly to blog posts from other sources.

An alternative solution is to export sub-trees to your Hugo site using ox-hugo. Because it allows you to generate blog posts from sub-trees (or entire files) at anywhere, it will help you centralize information. I was interested in this solution as well and tried it, but some of its defaults were not to my preference. It needs a workaround, so I didn't use it to write my blog this time. Maybe I will use it later.

Markdown still has an advantage of allowing you to use other text editors to edit contents. I personally prefer Typora as a Markdown editor, simply because it allows me to forget about my configuration and concentrate on text. However, the convenience of using the same format (Org) for every situation beats the awesomeness in most cases. I will use Org for my blog.


Hugo had a command named undraft which removes the draft status from a post and update its time stamp. This command has been obsolete since version 0.35. Instead, you can publish a draft post by taking the following steps:

  1. Insert a new time stamp using an expression (insert (format-time-string "%FT%H:%M:%S%:z")).

  2. Set the draft attribute to false.


Writing a blog is crucial in learning. Hugo is an editor-independent framework for publishing a blog site, but the following features of Emacs help you implement a workflow with it:

  • Compilation and projectile.

  • Snippet management using yasnippet or yankpad.

  • Writing in Org-Mode.

Because these techniques are applicable to other projects, you don't have to learn anything specific to blogging with Emacs.

The next challenge will be to export Org entries to the Hugo site using ox-hugo. It will be worked on someday.