My original plan of the aforementioned upgrade was that I was going to try to write migrations from Drupal 6 to Drupal 8. When I found out that it is not that complicated but it is quite annoying I decided to try out static website generators.
I ditched the unfinished Drupal with its own design and started from the beginning. Which static site generator am I going to use? As a first choice Jekyll was kind of suggesting itself. But I have some concerns about Ruby and gem from the past and it happened to me several times that the versions somehow mixed up in my computer and apps did not work.
I vetoed Gatsby for similar reasons. I know, JAMstack, React and stuff like that are extensively popular. But I don’t need to build a pyramid and install so many JS things to my computer because of a simple web. I could have continued with Drupal if I wanted to go this way.
So eventually I have chosen Hugo. One reason was declared (truthfully) speed, another reason was that the whole tool is basically one launchable file. The MacOS installation is a piece of cake. Moreover I am slowly learning the Go language in which is Hugo written. So another reason to immerse myself into it.
The first encounter with Hugo and hitting a wall
I downloaded Hugo following the instructions, installed it, ran a basic template with some visual theme and started to study its documentation. And that was the first stumbling block. I liked the Hugo documentation then and I like it even now. Same as when I opened it for the first time. But when you start building something specific, you may hit a wall just like I did.
I created files in markdown for a website content. But I needed a thing similar to the types of content in Drupal. Posts and entries to a web catalogue. And some common pages like “About Us”. Lists of these items. Arranged in several different ways. In every content some more advanced formatting than just a text column. Something like blocks. I won’t be writing HTML into markdown manually, will I?
In the end I got stuck with all this. Of course, you can find everything in the documentation. Some things not in detail, some things not very understandably put but it sure is there. There are many more things. But it is assumed you know what you are asking about. That, for example, you won’t look for an alternative to the Drupal blocks but for the WordPress shortcodes.
I became unhappy and played around with Jekyll for a while again...
This free video course will help you, too
But, as usually, by chance I came across an article by Mike Dane. From there I discovered his YouTube channel and in the end I spent some pleasant time by binge-watching his series on the static website generator Hugo.
Mike’s series is very nicely made. It can lead you step-by-step through the generator and a built-in server setting up. And also through adding various types of content, list building, mutual linking through categories and many more options that Hugo offers.
I recommend to look at the website of this lecturer. Because he has made other series on Jekyll, Gatsby, but also about C, C++, Ruby, Python, MongoDB and other stuff that a developer can encounter these days.
After watching all twenty-two lessons I was ready to get to work. I knew then that it was going to go smoothly now. Even though Mike doesn’t go through everything, he skips working with sources and images, he doesn’t go deep on CSS and JavaScript, he doesn’t pay attention to menu creating. But those are the things that you can easily manage with some internet research.
I few setbacks I have looked into
In the end I have built the web on an HTML template I bought. No matter how much I don’t like this solution and I also had to dedicate some time to remove the useless ballast. But more about that next time. Back to Hugo.
The basic template baseof.html, dividing into a heading, foot and other components, I managed all that with no problems. Thanks to the series I have mentioned above I also prepared individual types of content in Hugo, I used shortcodes to format the content entered to markdown files better.
And then I started to solve a few remaining troubles. I will list them briefly here, they might help somebody.
How to deal with formatted content inside a shortcode? The work with shortcode parameters is simple. Writing content between the shortcode tags too, the problem is that they are not being formatted by markdown. But what if you don’t want to write HTML into a shortcode entry in a content file? The solution is to replace in a template basic {{ .Inner }} by {{ .Inner | markdownify }}.
How to format a URL address in Hugo? Via a shortcode parameter I pass into its template a URL address. The whole address with “http” in the beginning. That’s fine for generating a link, less so for its visible part where I don’t want “http” to be visible for visitors. Hugo can parse a URL, so from https://www.maxiorel.cz you can make www.maxiorel.cz as follows: {{$url := urls.Parse (.Get "web")|}}{{ $url.Host }}.
How to insert an HTML template into another? In some parts of content templates I needed to insert a piece of an HTML code from another file. It’s simple: {{- partial "copy.html" . -}}.
How to work with images in Hugo? Work with sources is not included in Mike’s tutorial but you can find its description under “work with page sources” in the Hugo documentation. To me it wasn’t immediately clear what should I do to get an image included in front matter in markdown into an HTML template. A solution is quite simple, though. For a page, a post or other type of content don’t just create a file muj-clanek.md, but create a folder named muj-clanek, a file index.md inside it and into the same folder put also an image for your post.
In front matter you will have something like this:
--- title: "Můj článek" date: 2019-08-05T16:02:07+02:00 draft: true resources: - src: "obrazek.jpg" name: mainphoto - src: "fotka-1.jpg" name: gallery - src: "fotka-2.jpg" name: gallery --- Donec id elit non mi porta gravida at eget metus. Curabitur blandit tempus porttitor. Cras mattis consectetur purus sit amet fermentum. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Nullam quis risus eget urna mollis ornare vel eu leo. Sed posuere consectetur est at lobortis.
You will have an HTML template writing the content in a standard way via {{.Content}} and somewhere inside it you would like to write an HTML tag for connected images. One for the image tagged as mainphoto, the second one for all photos tagged as gallery. All images will be located in the same folder as the MD file with the content of your post.
In the first case use .Resources.GetMatch that returns the first result. I straight away used the fact that Hugo can make images smaller to a required size. More functions for image manipulation can be also found in the documentation. In this regard it is all quite understandable.
{{ with .Resources.GetMatch "mainphoto" }} {{ $img := .Fill "770x500" }} {{ $imgRetina := .Fill "1540x1000" }} <img class="img-full" src="{{ $img.RelPermalink }}" srcset="{{ $imgRetina.RelPermalink }} 2x" alt="{{.Title}}" loading="lazy"> {{ end }}
So I made two different sizes from one image and I wrote links to these files into the template.
Similarly I can go through all the gallery photos, here just instead of .Resources.GetMatch I will use .Resources.Match.
{{ with .Resources.Match "gallery" }} {{ range . }} {{ $img := .Fill "134x134" }} {{ $imgRetina := .Fill "268x268" }} <li class="work_img"><a href="{{ .RelPermalink }}"><img src="{{ $img.RelPermalink }}" srcset="{{ $imgRetina.RelPermalink }} 2x" alt="{{.Title}}" class="img-full" loading="lazy"></a></li> {{ end }} {{ end }}
How to add assets in Hugo along with their minification and print? Hugo supports by its pipeline even SASS and other pre- and post-processors of CSS and javaScript. For my purposes sufficed a simple minification of these files. The first step is their right placement. Copy them to the folder assets in your visual theme.
In the HTML template use the following entry:
{{ $js := resources.Get "js/script.js" | resources.Minify | resources.Fingerprint }} <script src="{{ $js.Permalink }}"></script>
You basically tell Hugo that it should find sources in the mentioned folder, there it will find a file by name, minify it and assign a print to it (that number in the end of a URL address to a script). A print is useful to you for solving problems with long cacheing in a browser when you edit a file in the meantime. After re-generating a web it just has a different name. On the second line there is only a path to a file written.
How to filter out several entries of a certain type of content for viewing on a front page of a web?
A thing that I could click in Drupal in a short while with the Views module here I had to think about for a while. I have a feeling I could not find the right preview of page selection according to a filter. But it is simple, like everything in Hugo:
{{ $pages := where .Pages "Type" "katalog" }} {{ range first 6 $pages }} <a href="{{ .RelPermalink }}">{{.Title}}/a> {{ end }}
The aforementioned writes the six newest entries of the catalogue type.
How to format a date and a time in Hugo? Time formatting in Hugo is quite a peculiar thing. However you should know that if you have a time like “ISO8601” stated in front matter, then the view in the day. month. format you can set in the template by writing {{ .Date.Format "2. 1." }}. And a year like this: {{ .Date.Format "2006" }}. And yes, 2006 is really there ;-)
A finished web built with Hugo
The Hugo generating including minification and especially image size changes is really very fast. To say that the folder public which you will then copy to a server was created in seconds is actually wrong. Even that is too long.
So with Hugo I was able to replace the original web built in Drupal quite easily. You will find it here: www.brnomasaze.cz. Setting up a fast and (in contrast to the original web) even a responsive web was possible for me, thanks to a template. More on this web in detail later. However regarding to Hugo:
- I use archetypes of content – a post, a massage type, the catalogue. And non-sorted pages.
- On the front page there are several different lists of these types of content sorted by various criteria and orders.
- The massage catalogue, massage types and posts – those are lists of various types of content.
- In the detail of every entry in the catalogue I use shortcode to generate the viewing of the contact information and the map. Corresponding values I write into the MD file into the front matter part.
And that’s all. If you also struggle with Hugo and have come across a problem, feel free to leave a comment. Maybe I can offer some advice. I will definitely continue to work with this web generator and I probably will convert several other webs that have some CMS from the past but content is not edited that often to it. Why to spend time with updates of something that can be replaced with a few HTML files.