turbin3
BuSo Pro
- Joined
- Oct 9, 2014
- Messages
- 613
- Likes
- 1,285
- Degree
- 3
The purpose of this thread is to aggregate as many Hugo generator tips and tricks into one place as possible. This will make for a great reference for those looking for a refresher with Hugo, or beginners looking to make sense of where to start. First off, a few of mine:
Dynamically Generated Table of Contents
I must have spent hours on this. In hindsight, I feel like an idiot. After trying and failing with a bunch of different methods......I found a totally copy/paste method, directly from the Hugo docs, that totally works! Hopefully this will save some people a lot of pain:
Hugo Table of Contents
Basically, it takes the headings in your post and uses them to generate a nav element with an unordered list of those headings. This is excellent for lengthy posts where you want to display an easy to use sub-nav, within the post, for navigating around it.
The awesome thing is, you can simply paste this into your relevant theme template, wherever you prefer to use it. Then just style with a bit of CSS, and it's kind of a set it and forget it affair. Just write your posts, add headings when you want, and the in-post nav will generate itself.
Using Find & Replace Regex in Hugo
There's actually a built in function for this. This can be really useful if you need to do something like replace all of a particular type of thing sitewide, like maybe reformatting a particular word, URL, etc. Just be careful, as regex replace is powerful and indiscriminate if applied incorrectly.
I've used this before with sites I've migrated to Hugo, that had a significant number of posts. Sometimes you might have things like old links, certain words (brand names, etc.) etc. that are too numerous to deal with manually. There are of course other ways to deal with this, including more permanent ways, but a regex replace is a quick and dirty method to just get the job done.
Base64 Encoding & Decoding
Yep, Hugo even has built in functionality for base64 encoding and decoding! There are some particularly cool possibilities with this. For example, for certain purposes you may want to base64 encode an item to protect against low-barrier-to-entry site scrapers that don't account for these things (trying to gobble up your email addresses and stuff!).
So with this, maybe you could encode an element and then decode it elsewhere when needed. Maybe in some cases you might use Hugo in a theme template to encode a certain element, and elsewhere maybe you use Javascript to decode it. This could help protect against at least the low-barrier stuff from scraping form data, emails, other contact info, etc.
HTML / CSS / JS Minification Build With NPM
If you don't have NodeJS and NPM installed (NodeJS installs both), I highly recommend it! NPM is extremely handy for quickly getting a set of scripts and commands together to add capabilities to pretty much anything. In this case, we'll basically add a processing pipeline to minify our HTML, CSS, and JS files. I can't remember why, but with this particular setup I wasn't concatenating files, probably because some sort of UI issues I was too lazy to debug.
If this is your first time working with NPM, once you have it installed you'll want to go to the main directory for whichever Hugo site you're working with. Then run this command:
This will create a package.json file in the root of your site's directory. The package.json is basically the "settings" file. NPM will basically create a "project" in this site's directory, and the files of any packages you choose to install will go under a "node_modules" directory. If you gaze into this directory in horror, don't worry! You will rarely if ever need to venture in there.
We configure our settings in package.json, maybe create a few other files in our site's root directory for certain packages we may have installed (these are also basically "settings" files), and NPM does the work for us! Here's a package.json you can work with for this project:
So, looks like there's a LOT going on here! Don't worry, I'll break it down. The top part is usually your main configuration, site info, basic or custom commands, etc. Pay attention to the "devDependencies" section, as well as the "babel" section below. If you already have NPM and copy those sections into your package.json, you can simply run the "npm install" command from your command line and NPM will install those packages for you!
Creating & Running Custom NPM Commands
There are also a few other useful things in this example. One is a custom command ("server") to run the Hugo server. In this case, I'm using standard Hugo flags to run the local test server for that site, with the "watch" flag (-w or --watch) so it will live reload on changes. I'm also using the -v command (verbose) which can be useful for debugging and seeing more error info.
Deploying to AWS S3 With NPM
Additionally, in this instance I also have the AWS CLI installed on this particular system, and I've added an NPM command ("deploy") to deploy the built site (which gets built to the "public" folder) to S3. This command uses the "sync" option as well as the --delete flag, which will update only the files that have been changed, added, or removed, which is super useful.
Setting Up Gulp + NPM To Minify Resource Files
Now let's setup a javascript file to setup the minification process for us. Create a file in the root of your Hugo site called "gulpfile.babel.js". I forget if this is already created for you, once you've run the "npm install" command to install dependencies. If not, just create the file and paste this in:
Basically, the way this works is, when you run the "npm run build" command ("build" is the custom command we created in the package.json above), it runs Hugo's built in command to build the site to the "public" folder. NPM then runs the "gulp build" command automatically after this. The code in this gulpfile.babel.js file then minifies the files in your public folder, which are the ones you would be deploying to wherever you decide to host the site. The idea here is, we're not making any permanent changes. This is just post-processing the built site to optimize it a bit, which is a pretty useful concept.
That's about all I have tonight. I'd also encourage anyone new to Hugo to ask questions here! I know many of you are getting started with Hugo. I'm sure @built has a few questions. When I first started with it, there was a bit of a learning curve. The Hugo docs have improved quite a bit, though I'd say the "usability" is still a bit lacking for those that are not quite traditional developers.
Dynamically Generated Table of Contents
I must have spent hours on this. In hindsight, I feel like an idiot. After trying and failing with a bunch of different methods......I found a totally copy/paste method, directly from the Hugo docs, that totally works! Hopefully this will save some people a lot of pain:
Hugo Table of Contents
Basically, it takes the headings in your post and uses them to generate a nav element with an unordered list of those headings. This is excellent for lengthy posts where you want to display an easy to use sub-nav, within the post, for navigating around it.
The awesome thing is, you can simply paste this into your relevant theme template, wherever you prefer to use it. Then just style with a bit of CSS, and it's kind of a set it and forget it affair. Just write your posts, add headings when you want, and the in-post nav will generate itself.
Using Find & Replace Regex in Hugo
There's actually a built in function for this. This can be really useful if you need to do something like replace all of a particular type of thing sitewide, like maybe reformatting a particular word, URL, etc. Just be careful, as regex replace is powerful and indiscriminate if applied incorrectly.
I've used this before with sites I've migrated to Hugo, that had a significant number of posts. Sometimes you might have things like old links, certain words (brand names, etc.) etc. that are too numerous to deal with manually. There are of course other ways to deal with this, including more permanent ways, but a regex replace is a quick and dirty method to just get the job done.
Base64 Encoding & Decoding
Yep, Hugo even has built in functionality for base64 encoding and decoding! There are some particularly cool possibilities with this. For example, for certain purposes you may want to base64 encode an item to protect against low-barrier-to-entry site scrapers that don't account for these things (trying to gobble up your email addresses and stuff!).
So with this, maybe you could encode an element and then decode it elsewhere when needed. Maybe in some cases you might use Hugo in a theme template to encode a certain element, and elsewhere maybe you use Javascript to decode it. This could help protect against at least the low-barrier stuff from scraping form data, emails, other contact info, etc.
HTML / CSS / JS Minification Build With NPM
If you don't have NodeJS and NPM installed (NodeJS installs both), I highly recommend it! NPM is extremely handy for quickly getting a set of scripts and commands together to add capabilities to pretty much anything. In this case, we'll basically add a processing pipeline to minify our HTML, CSS, and JS files. I can't remember why, but with this particular setup I wasn't concatenating files, probably because some sort of UI issues I was too lazy to debug.
If this is your first time working with NPM, once you have it installed you'll want to go to the main directory for whichever Hugo site you're working with. Then run this command:
Code:
npm init
We configure our settings in package.json, maybe create a few other files in our site's root directory for certain packages we may have installed (these are also basically "settings" files), and NPM does the work for us! Here's a package.json you can work with for this project:
Code:
{
"name": "My Site",
"version": "1.0.0",
"description": "Check out my awesome site!",
"main": "index.html",
"scripts": {
"server": "hugo server -w -v",
"build": "hugo -v && gulp build",
"deploy": "aws s3 sync public/ s3://www.examplesite.com/ --delete"
},
"devDependencies": {
"babel-preset-es2015": "^6.5.0",
"babel-register": "^6.5.2",
"gulp": "^3.9.1",
"gulp-cli": "^1.2.1",
"gulp-htmlmin": "^1.3.0",
"gulp-clean-css": "^3.0.4",
"gulp-uglify": "^2.1.2",
"gulp-shell": "^0.5.2",
"run-sequence": "^1.1.5"
},
"babel": {
"presets": [
"es2015"
]
},
"author": "Turbin3",
"license": "ISC"
}
So, looks like there's a LOT going on here! Don't worry, I'll break it down. The top part is usually your main configuration, site info, basic or custom commands, etc. Pay attention to the "devDependencies" section, as well as the "babel" section below. If you already have NPM and copy those sections into your package.json, you can simply run the "npm install" command from your command line and NPM will install those packages for you!
Creating & Running Custom NPM Commands
There are also a few other useful things in this example. One is a custom command ("server") to run the Hugo server. In this case, I'm using standard Hugo flags to run the local test server for that site, with the "watch" flag (-w or --watch) so it will live reload on changes. I'm also using the -v command (verbose) which can be useful for debugging and seeing more error info.
Deploying to AWS S3 With NPM
Additionally, in this instance I also have the AWS CLI installed on this particular system, and I've added an NPM command ("deploy") to deploy the built site (which gets built to the "public" folder) to S3. This command uses the "sync" option as well as the --delete flag, which will update only the files that have been changed, added, or removed, which is super useful.
Setting Up Gulp + NPM To Minify Resource Files
Now let's setup a javascript file to setup the minification process for us. Create a file in the root of your Hugo site called "gulpfile.babel.js". I forget if this is already created for you, once you've run the "npm install" command to install dependencies. If not, just create the file and paste this in:
Code:
import gulp from 'gulp'
import htmlmin from 'gulp-htmlmin'
import cleanCSS from 'gulp-clean-css'
import uglify from 'gulp-uglify'
import runSequence from 'run-sequence'
import shell from 'gulp-shell'
gulp.task('hugo-build', shell.task(['hugo']))
gulp.task('minify-html', () => {
return gulp.src('public/**/*.html')
.pipe(htmlmin({
collapseWhitespace: true,
minifyCSS: true,
minifyJS: true,
removeComments: true,
useShortDoctype: true,
}))
.pipe(gulp.dest('./public'))
})
gulp.task('minify-css', () => {
return gulp.src('public/**/*.css')
.pipe(cleanCSS())
.pipe(gulp.dest('./public'))
})
gulp.task('minify-js', () => {
return gulp.src('public/**/*.js')
.pipe(uglify({
preserveComments: 'all',
}))
.pipe(gulp.dest('./public'))
})
gulp.task('build', ['hugo-build'], (callback) => {
runSequence(['minify-html', 'minify-css', 'minify-js'], callback)
})
Basically, the way this works is, when you run the "npm run build" command ("build" is the custom command we created in the package.json above), it runs Hugo's built in command to build the site to the "public" folder. NPM then runs the "gulp build" command automatically after this. The code in this gulpfile.babel.js file then minifies the files in your public folder, which are the ones you would be deploying to wherever you decide to host the site. The idea here is, we're not making any permanent changes. This is just post-processing the built site to optimize it a bit, which is a pretty useful concept.
That's about all I have tonight. I'd also encourage anyone new to Hugo to ask questions here! I know many of you are getting started with Hugo. I'm sure @built has a few questions. When I first started with it, there was a bit of a learning curve. The Hugo docs have improved quite a bit, though I'd say the "usability" is still a bit lacking for those that are not quite traditional developers.