Hugo Export Module for Drupal 8
Mar 26, 2020 | Last edit: Dec 31, 2020
Static site generators are proving to be valuable tools to extend or augment a content-management system like Drupal. I've been experimenting with Hugo to understand how adding it to a Drupal site can bring some advantages, like simplifying the site architecture and lowering the security risk. At the same time, I've had to delve into the challenges of maintaining two tools and how to manage the content hand-off from Drupal to Hugo.
My conclusion: it's totally doable and a good solution in some cases!
One way to consider it is that Drupal becomes a build tool for the site, or a protected resource on a private network. The web site, then, is the HTML, etc., files which can be deployed in any number of ways.
Introducing the Hugo Export Module
One decision when migrating a site is whether to use the current system to export content, or the new one to extract content. With Drupal, it seems much easier to leverage Drupal's data-modelling tools to prepare our content and export it. Enter the Hugo Export module -- a work in progress.
Among the most valuable tools that Drupal offers are its menu system, taxonomy tools, and Views to generate custom-defined lists of content. This module seeks to build upon those assets, allowing you to manage them in Drupal and transfer it all to Hugo.
Menus
The first option for exporting your content from Drupal is to use a menu. The module creates a new menu for you, or you can use an existing one. Add nodes to the menu, set the item weights, create submenu lists and save. The module will preserve that structure and export not just the menu configuration, but all of the content items that are referenced by it. Copy those files into your Hugo site, and you're done.
Use case: export an informational site with a pre-defined page structure.
Views
A second option is to export a View of content items. With Views, you can create custom lists of content based on certain parameters, like taxonomy field values or creation dates. The module will export that content and place it in a folder with the same name as the View. Copy this folder into the content/ folder of your Hugo site and it becomes something called a "Section." (In Hugo-speak, this is something you can reference as a subset of all Pages, which can be very handy when creating a block of related items or non-page content.) Or you can copy the items into the content/ folder and Hugo will consider them as the main page structure.
Use case: export a feed of blog posts or other content of a certain type, with no set structure or hierarchy.
Content Types and Taxonomy
Currently, the module supports the default fields and vocabulary that come with a base install of Drupal 8. So exporting the "Article" and "Basic page" types will work, along with the "Tags" taxonomy field. The default Image field is also included; the original file is copied to a public/ folder, to be copied over to your Hugo site.
Each exported item is rendered to a yaml file, which is the default for Hugo. Fields are mapped with sensible labels, and the body content is transferred as HTML, with no processing. Fields that are included: date created, date edited, URL alias, author name.
As a work in progress, there are some limitations:
- custom fields are not supported now. How best to define the mapping and format of those fields?
- taxonomy fields are rendered as a list of term names. How best to override that?
- no processing is done on body content, i.e. for replacement of Media items or tokens.
- no translation support.
Theming in Hugo
Hugo has plenty of free-to-use themes that you can download and use. Some may require minor tweaks to rename an archetype/content-type. But if you choose to build your own theme, this is where you'll spend most of your time in Hugo. Stay tuned for another post on my experience with building a theme.
Why Hugo?
Hugo is written in Go, something that I've been learning. It seems quite simple compared to Gatsby, a static site generator that is commonly paired with Drupal. Hugo is fast to build. It supports multi-language options, menus and taxonomies in ways that mirror Drupal. Designing for a Hugo site is quite simple -- it's just HTMl and CSS to start with. No React.
So I need to learn Go? I don't feel like I'm writing Go when I build a site, but I certainly recognize there are conventions that will be confusing for a newcomer. One example: it's common in Go to define a variable with this syntax:
one := 1
The ":=" is the "short assignment statement" and something you see a lot. Unlike PHP, there is no special character to denote a variable, like $.
In Hugo templating, you may see:
$currentNode := .
First, the template language seems to prefer that variables start with a $. That's not a Go thing. Second, Hugo has a strong notion of context which is something like a bundle of variables that are defined in a certain scope. At first, this is rather hard to comprehend. But suffice to say in the example above, we are passing the entire context which is contained in the dot "." (in this case, a page template for a single item) to that new variable $currentNode. Look for more info on managing variables in a Hugo theme in a future post.
Why not Drupal?
Drupal is an excellent system for data modelling and content management. Out of the box, it has too many excellent features to mention. But like any tool, it isn't something you use in every situation. So when would I do this?
Drupal to Hugo:
- you're unable to keep up with Drupal security updates, or would rather not worry about potential risks from SQL, etc.
- you don't like developing themes or designing in Drupal and want something simpler.
- you need more flexibility or higher performance in your server architecture.
- you can't or don't want to maintain a public-facing server with PHP, SQL, etc.
At the same time, this would be an unwise decision for other situations.
Why to Not Abandon Drupal:
- you have dynamic content that changes frequently.
- you need to collect data from users, through forms, etc.
- you need to maintain user access control.
- you don't have the bandwidth to maintain two separate systems.
Drupal to Hugo Cheatsheet
- "content types" in Drupal are called "archetypes" in Hugo.
- content items are typically written as markdown files in Hugo.
- frontmatter is a Hugo term for metadata that defines a content item. It's written in yaml format at the top of a content item. In Drupal, this is like the bundle settings.
- include the "kind: {type}" field to tell Hugo to render a content item as a specific content type.