Following up on my previous post on how to integrate Hugo with Emacs, here’s my solution to automatically combine CSS files, thus cutting down on the number of roundtrips to load the page.

Hugo modifications

Only a simple modification to the Hugo site itself is needed, the rest is done in the upload script. I set the included stylesheets in my config.toml parameter settings:

    stylesheets = ["fonts.css", "raleway.css", "pure-min.css", "grids-responsive-min.css", "custom.css", "figures.css", "highlight.css"]

and include them in the template as follows:

  {{ range .Site.Params.stylesheets }}
    <link href="/css/{{ . }}" rel="stylesheet" type="text/css" />{{ end }}

This assumes that all style files are found in the css subdir of an appropriate static file directory.

Upload script modifications

I modified my previous upload script to include some rewriting of the CSS files. The whole script now looks like this:

cd ~/git/blog

rm -rf public

STYLESHEET_PATHS="static/css themes/nofancy/static/css"

    stylesheets=$(grep 'stylesheets = ' config.toml | sed -e 's/[",]//g' -e 's/stylesheets = \[//' -e 's/\]//')
    for f in $stylesheets; do
        for d in $STYLESHEET_PATHS; do
            if [ -f "$d/$f" ]; then cat "$d/$f"; break; fi

get_stylesheets | python -m rcssmin > static/css/combined.css

conf=$(mktemp config-XXXX.toml)
sed 's/stylesheets = .*/stylesheets = ["combined.css"]/' config.toml > $conf

hugo -d public --config=$conf
rm -f $conf

# Remove source css files
find public -name '*.css' -not -name combined.css -delete

# gzip files so nginx can serve them compressed
find public \( -name '*.js' -or -name '*.css' -or -name '*.svg' -or -name '*.html' -or -name '*.ttf' \) -exec gzip -k9 '{}' \;

rsync -rtpl --delete public/ kau:/srv/http/blog/

Update: The cssmin command has been changed to invoke the rcssmin Python module.

The get_stylesheets() function extracts the configured stylesheets from the config file, looks for them in either the top-level static/css directory or in the theme and simply outputs the content of the file using cat. The results of running the function is a concatenation of all the configured stylesheets, which is simply passed to cssmin and written to the combined.css file.

The script then creates a temporary configuration file which has the list of style sheets replaced with just the combined.css file, and runs Hugo with that config file. The extra CSS files are then removed from the output directory and everything is compressed before being synced to the server.

The solution is definitely a little hackish (most most prominently using grep and sed to extract the style sheets in this way is prone to breaking), but it does work, as can be witnessed by inspecting the source code of this page.