Moving to Hugo
Several weeks ago, my Docpad installation got screwed. There was some errors when I tried to run it. My assumption was because I just moved to Node.js 5.x, so I tried to upgrade (or re-install it, maybe) it. Though the errors are gone, it did not work as it used to be, it failed to build my blog properly — or I just forgotten how to use it, that’s another possibility.
Since I was looking for alternatives, I found Hugo, a static site generator created by Steve Francia using Go. The documentation was comprehensive enough to get me started. Thanks to Hugo I got this blog up and running again.
After digging a bit deeper into Hugo, Compared to Docpad, Hugo came out on top. The first and foremost deciding factor to me was speed. Docpad took more than 5 seconds to generate my blog with just merely 7 posts in it, and (most) sometimes it took longer than that. It was quite unpleasant experience when I drafted a blog post and want to preview it but need to wait that much and to make it worse I did it quite often, conscious or un-consciously. Amazingly, Hugo took only around 100ms to generate my blog, that was 500 time faster, awesome!
So, if you have the same problem as mine or just want to try new things, here’s my Hugo How To.
Setup the site
Install Hugo and get it running
Hugo is easy to install, you can download its binary or install it via Homebrew like I did or if you feel a bit adventurous you might want to build it from source, which might as well quite easy. To get Hugo runs actually took quite minimal effort. The quickstart do a really good job to explain the step by step.
One more thing I like about Hugo is it provides a better working
structure compared to Docpad. When creating a new site by running
hugo new /path/to/site
, Hugo creates a working skeleton
structure comprises archtypes
, content
, data
, layouts
,
static
and themes
. Those directories are where we supposed
to put pre-configured front matter, blog contents (posts),
data, site layouts, static files and themes that we want to use.
The Source Organization
section elaborates on the directory structure deeper.
Pick your theme and make it yours
Hugo comes up with quite a lot ready to use themes.
You can try all the themes by simply clone all the themes
and run hugo server -t <theme-name>
. The command tells Hugo
to load the specified theme and use it to render the site then
runs a HTTP server to serve the generated site. If no directory
given (using -d
option), Hugo generates the site to your
machine’s memory when running the hugo server
command.
If none of the themes up to your liking, then you can customize them quite easy. You don’t need edit directly the theme you are using, you only need to override the specific part to your liking instead. The easiest way to do this is by copying the part that you want to change from the themes directory to its respective directory in your site, e.g.,
cp /themes/redlounge/layouts/index.html layouts/index.html
and start modifying it. The way Hugo determines the layout
is to find respective files in layouts
then using defaults
layouts/_defaults
if the desired file can’t be found.
The search is then propagated to the used theme themes/used-theme
if the file still not found.
For this blog, I choose hugo-redlounge
as the base of my blog theme and customized it as you see now. Most of the customizations are related to styles, hence,
I use SCSS to modularize my custom CSS.
I put all the SCSS files in a separate src
directory and only
the resulting CSS is put in the static
directory to be used.
Another way is to clone Steve Francia’s website, which looks
really awesome and start to customize it as you see fit.
Migration
Migrating from Docpad to Hugo should be easy assuming the posts
are written in markdown format. In my case, I just needed to copy all posts into content/post
. Copying the markdowns alone should be
enough to make Hugo renders them. However, you might want to
change the posts’ front matter
to adhere Hugo’s format. Next is to migrate all the static files
to directory static
.
Hosting on GitHub
There are several ways to deploy generated site to GitHub-Pages.
Using git subtree
is one of them like shown in
this tutorial.
The cons of this method is that you also keep track the generated
site directory to your working repository. This is a problem for
me as I have quite slow internet connection so I need the
the repository to be as small as possible.
To solve the problem, I did is similar to what I did
previously to Docpad: make the generated site directory (default
is public
) ignored then clone the existing gh_pages
(create one if necessary) to directory public
. When deploying to GitHub, the sequence is: copy public/.git
, public/.gitignore
somewhere else, generate the site, put back .git
and
.gitignore
to public
then commit and push it.
# Do this only one time when setting up public dir.
# Assuming you are inside your working directory.
git clone [email protected]:user/user.github.io.git public
echo "public" >> .gitignore
# commit and push your repository
git commit -m "ignore public"
git push origin master
# Deployment sequence
# create temporary directory
mkdir tmp
# copy .git/ to temp
cp -r public/.git tmp/.git
cp public/.gitignore tmp/.gitignore
# clean out directory public and regenerate htmls
rm -rf public
# generate static htmls
hugo -t some_theme
# copy back the git files
cp -r tmp/.git public/.git
cp tmp/.gitignore public/.gitignore
# go to the out folder
pushd public > /dev/null
# create .nojekyll file
# https://github.com/blog/572-bypassing-jekyll-on-github-pages
touch .nojekyll
# add and push to github pages
git add -A
git commit -m "`date`"
git push -f origin master
# change back to root dir
popd > /dev/null
# remove temp directory
rm -rf tmp
Automation
What I did next is to automate repetitive tasks such as deployment steps above, which is quite lengthy and prone to errors. For this project I decided to use GNU Make as the build tool — I used this bash script when dealing with Docpad previously. But, why Make? Why not! Make has similar capabilities with other recent build tools like Cake, Gulp or Grunt. Moreover, my machine has it pre-installed. Currently, I’m still novice in Make, hence my terrible looking Makefile. Following this, I plan to use Make at my office as the build tools of the project I’m working on. Hope I can be more proficient along the time.
Overall, Hugo is a nice tool to play with. It is very fast, customizable and easy to operate. There are a lot of Hugo’s features that yet to explore, e.g., shortcodes, taxonomies, scratch, etc. Up to this point, I am a satisfied Hugo’s user, but, we’ll see.