Renato Ivancic - Software Engineer

Background image

This blog is build with Hugo

Web Development

What is the best way to create a blog. The tool for building it, should be simple as possible and use latest technology. The content will not change too often and it won’t be customizable for special user groups. Like in old days I can use static pages. From personal experiences I would like to avoid to use bloated Joomla or WordPress installation. Also there is no need to use additional server resources (RAM, CPU) even the database becomes obsolete which adds to responsiveness. With all this in the account, the big part of application layer security vulnerabilities disappear. No need to always update the CMS to the latest and greatest version because there were security bug fixes. But putting together a menu and all the navigation can be quite cumbersome work. We should define the rules of how the page is displayed once and then when the content is changed, the whole static page should be build by these rules. With static page it is also very easy to write and view posts offline. If you are not running the server alone, there is almost zero dependency on the service provider. For moving site to another location is just copy paste operation.

Hugo Logo

Hugo initialization

Some time ago working colleague mentioned static page generator Hugo. I gave it a try. It has support for multiple formats and is ideal for blogs, portfolios, static pages for small companies. It is written in Go language. Per default the URLs are prettified. At the time the version 0.14 is available which seems to work astoundingly well.

If you want to use Hugo as your site generator, simply install the Hugo binaries. The Hugo binaries have no external dependencies. On the Mac you can install Hugo with brew:

    brew install hugo

After the Hugo is installed the simple command initialize the project structure needed to build simple page without content.

    hugo new site /path

All the created content that should be transformed into html pages and displayed for the user should reside in the /content directory of the Hugo initialized page directory. There are however no rules yet how to render the content. The easy way is load some theme that will display created content. And then once you go trough the layouts of the theme you can better understand how the whole templating is working underneath. You see from the command that themes must be in a themes directory.

    mkdir themes
    cd themes
    git clone URL_TO_THEME

Because the material design is so hipe nowadays the material-design theme caught my eye. So lets say the material-design theme is installed then the result page can be shown with specifying the theme with –theme option. So in the themes directory new subdirectory material-design is created which contains layout, images and static data like css and javascript files.

    hugo server -D --theme=material-design

Hugo server command renders content to HTML pages and runs the local server on your machine which is usually available on localhost:1313. Instead of specifying the theme every time running the server, the theme can be specified in the config file config.toml. But server doesn’t actively watch for the changes in the config file so you must restart the server again to take configuration changes into account.

    theme="material-design"

The result is simple styled web page, with menu and navigation but the content is missing.

Content

All the content files that represents your single page reside in the content directory in the root of the project. Subfolders then represents the content section. Every content file in hugo is basically spliced into two parts. The first one is front matter, in which all the meta data is defined. Then the content to be displayed follows. In the front matter I am using toml format, although json is also supported and the markdown for content. In the front matter the properties like title, slug, tags, categories, publish date and status are saved. The status of the file can be set to draft so it is displayed only if we are previewing the built page on a local machine.

IDE & Gradle

I am used to develop things in IntelliJ IDEA. This project is also an IDEA project. The idea-multimarkdown plugin is really useful to write the content in markdown.

I am also slowly becoming friend with Gradle. For testing the end result on local machine we can use the hugo’s build in server which can give us the preview. It can be run with simple gradle task hugoServer.

    task hugoServer(type:Exec) {
    
        // Move to the dir of the hugo page.
        workingDir = file('./Page/')
    
        // Run the server and keep the drafts.
        commandLine 'hugo', 'server', '-w', '-D'
    }

When I’m satisfied with current work on local environment, I can publish it with single gradle task hugoPublish. First the hugo command is run which builds the page. Then the apaches ftp ant tool uploads the result on server.

    task uploadFtp << {
    
        // Upload the build static files with ftp to the server.
        ant {
            taskdef(name: 'ftp',
                    classname: 'org.apache.tools.ant.taskdefs.optional.net.FTP',
                    classpath: configurations.ftpAntTask.asPath)
            ftp(server: "server_ip", userid: "[email protected]", password: "*********") {
                fileset(dir: "Page/public/")
            }
        }
    }
    
    task hugoBuild(type: Exec) {
    
        // Move to the dir of the hugo page.
        workingDir = file('./Page/')
        // Build final hugo page.
        commandLine 'hugo'
    }
    
    task hugoPublish(dependsOn: ['hugoBuild', 'uploadFtp']) {
    
        uploadFtp.mustRunAfter hugoBuild
    }

Page summary

I had a problem with autogenerated summaries. Its used to compile the overview page of the posts. The content at the beginning of the page was not appropriate to build autogenerated content summary. Autogenerated content for example contained code excerpts, it just takes first 70 words.

Autogenerated Summary

User defined summary split does not help as well, because summary begins from the top till the defined split. But in my case I would like to provide tottaly specific txt for the summary. The solution is to define custom Front matter variable called summary.

Front matter:

+++
...
headline = "Formatting dates in java"
description = "How to properly format dates in java 7 and 8."
summary = "Short summary with examples about formatting dates in Java 7 and 8. I decided to wrote it down as I found inconsistency of differend types of formatters used and misunderstanding of formatter patterns."
+++

To be able to use cusstom summary variable instead of autogenerated summary follow next step. In the content.html inside of the layout directory file that is responsible to render pages in index page. Replace

<p>{{ .Summary }}</p>

with

<p>{{ if .Params.summary }}{{ .Params.summary }}{{ else }}{{ .Summary }}{{ end }}</p>

Now the summary contains desired custom content.

Custom Summary

Issues

The issue is that in order to use the plain Hugo as an CMS, the end user needs to have the know how about Markdown or any other language for building content of the pages. Till now there is no WYSIWYG content editor build in directly in Hugo.

The documentation is well done, but still at some points you need a few tries to get things right.

Sources

[gohugo.io] (https://gohugo.io/)

[markdown] (http://daringfireball.net/projects/markdown/syntax)

[gradle building tasks] (https://docs.gradle.org/current/userguide/more_about_tasks.html)

[gradle ftp] (https://docs.gradle.org/current/userguide/organizing_build_logic.html)

[apache ant ftp] (https://ant.apache.org/manual/Tasks/ftp.html)

Custom summaries

#Hugo #Gradle #static web page