Managing This Site
Ben Bolton
- 7 minutes read - 1346 wordsThis site is built with Hugo — a static site generator written in Go. Everything is plain files: markdown for content, TOML for config, HTML templates for layout. There’s no database, no CMS, no server-side code. Hugo reads your files and builds a static site you can deploy anywhere.
This post covers how to do the most common tasks yourself.
How the Site is Structured
blog/
├── hugo.toml # Site configuration
├── content/ # All your pages and posts
│ ├── _index.md # Homepage content and layout
│ ├── about.md # About page
│ ├── gallery.md # Gallery page
│ ├── engineering/ # Engineering section
│ │ ├── _index.md # Section landing page
│ │ └── *.md # Individual posts
│ └── posts/ # Blog posts
│ ├── _index.md # Section landing page
│ └── *.md # Individual posts
├── layouts/ # Custom templates (override the theme)
│ ├── home.html # Homepage layout
│ ├── _default/
│ │ └── gallery.html # Gallery page layout
│ └── _partials/
│ ├── site-header.html # Banner/header override
│ └── site-footer.html # Footer with social links
├── static/
│ ├── images/ # Images used in pages/banners
│ ├── css/
│ │ ├── custom.css # Global CSS tweaks
│ │ └── lightbox.css # Gallery lightbox styles
│ └── js/ # Custom JavaScript
└── themes/ananke/ # The base theme (don't edit this directly)
The theme handles all the base styling and navigation. The layouts/ folder in the root is where you override or extend it — anything you put here takes priority over the theme.
Running the Site Locally
hugo server -D
The -D flag includes draft posts. Open http://localhost:1313 in your browser. Hugo watches for file changes and reloads automatically.
To build the final static output:
hugo --minify
This generates everything into the public/ folder, ready to deploy.
Writing a New Post
The quick way
hugo new engineering/my-new-post.md
Hugo creates the file at content/engineering/my-new-post.md with front matter pre-filled. Replace engineering/ with posts/ for a blog post.
The manual way
Create a .md file directly in the right content folder. Every file needs front matter at the top — this is metadata Hugo uses to build the page:
---
title: "My Post Title"
date: 2026-03-14
draft: false
featured_image: "/images/homepage.jpg"
description: "A short summary shown in listings and meta tags."
tags: ["terraform", "aws"]
---
Your content starts here.
Key front matter fields:
| Field | Purpose |
|---|---|
title | Page title shown in the browser and banner |
date | Publication date — affects ordering |
draft | Set to true to hide from the built site |
featured_image | Banner image shown at the top of the page |
description | Subtitle shown on the banner and in listings |
tags | Used to group related posts |
Writing content
Everything below the front matter is standard Markdown:
## A Heading
Normal paragraph text. **Bold**, _italic_, `inline code`.
```bash
# A code block with syntax highlighting
terraform init
- Bullet list item
- Another item
---
## Banner Images
### Changing the banner for a single page or post
Every page can have its own banner image. Set `featured_image` in the front matter pointing to a file in `static/images/`:
```yaml
featured_image: "/images/my-banner.jpg"
Drop the image file into static/images/. The /images/ path maps directly to static/images/ — Hugo serves everything in static/ at the root.
If you don’t set featured_image on a page, the header falls back to a plain dark bar with no image.
Changing the banner for the entire Engineering section (and its posts)
The Engineering section landing page (content/engineering/_index.md) and each individual post within it each have their own featured_image front matter field. To use a different image across the whole Engineering section, you need to update two things:
1. Update the section landing page (content/engineering/_index.md):
---
title: "Engineering"
featured_image: "/images/engineering-banner.jpg"
---
2. Set the same image as the default in each post’s front matter:
---
title: "My Post"
featured_image: "/images/engineering-banner.jpg"
---
Or, if you want all Engineering posts to automatically inherit from the section without setting it on every post, you can use Hugo’s cascade feature in content/engineering/_index.md:
---
title: "Engineering"
featured_image: "/images/engineering-banner.jpg"
cascade:
featured_image: "/images/engineering-banner.jpg"
---
With cascade set, every post inside content/engineering/ will use that image unless they explicitly override it with their own featured_image. Drop the image file in static/images/ first, then update the front matter.
Adding Photos to the Gallery
The gallery automatically picks up any image dropped into assets/images/gallery/. Hugo processes them at build time — generating a 300×300 thumbnail and a 1600×1600 large version for each one.
Steps:
- Copy your images into
assets/images/gallery/ - Use
.jpg,.JPG,.png, or.webp— avoid HEIC (browsers can’t display it) - Avoid spaces in filenames — use hyphens instead:
my-photo.jpgnotmy photo.jpg - Run
hugo server— the gallery rebuilds automatically
To convert HEIC files from your iPhone on macOS:
sips -s format jpeg photo.HEIC --out photo.jpg
The lightbox (click to expand, arrow keys to navigate) is handled automatically — no extra work needed.
Adding a New Section
If you want a new top-level section (e.g. /homelab/):
1. Create the content folder and a section index:
mkdir content/homelab
Create content/homelab/_index.md:
---
title: "Home Lab"
featured_image: "/images/homepage.jpg"
---
2. Add it to the navigation menu in hugo.toml:
[[menu.main]]
identifier = "homelab"
name = "Home Lab"
url = "/homelab/"
weight = 3
The weight controls the order in the nav bar — lower numbers appear first.
3. Add posts to the section by creating .md files inside content/homelab/.
Creating a Custom Page Layout
By default every page uses the theme’s single page template. If you need something different (like the gallery), create a layout file in layouts/_default/.
Option 1 — Set a layout in front matter:
---
title: "My Custom Page"
layout: "mycustom"
---
Then create layouts/_default/mycustom.html. Hugo will use it for any page with layout: "mycustom" set.
Option 2 — Override a specific section:
Create layouts/engineering/single.html to override the layout for all Engineering posts, without affecting anything else.
Every layout file wraps its content in {{ define "main" }}:
{{ define "main" }}
<main>
<h1>{{ .Title }}</h1>
{{ .Content }}
</main>
{{ end }}
.Title and .Content come from the page’s front matter and markdown body respectively.
Editing the Site Config
hugo.toml in the root controls site-wide settings:
baseURL = 'https://ben.white-wells.com/'
title = "Ben's Blog"
theme = "ananke"
paginate = 3 # Number of posts shown per page before pagination
[params]
author = "Ben Bolton"
featured_image = "/images/homepage.jpg" # Default banner for the site
custom_css = ["css/custom.css"] # Extra CSS files loaded on every page
show_reading_time = true
The navigation menu lives here too — add, remove, or reorder entries under [menu].
Custom CSS
static/css/custom.css is loaded on every page. It handles a few site-wide tweaks:
- Banner height — fixed at
40vhon mobile and50vhon desktop so all pages look the same regardless of whether the page has a title in the banner - Nav bar — forced into a single row on mobile with scaled-down text so the site title and menu links don’t stack
- About page — hides the duplicate
<h1>that would otherwise appear twice (once in the banner, once in the article body)
Use it for small global tweaks. For page-specific styling, prefer inline <style> blocks inside the content file itself — the homepage (content/_index.md) does this for the two-column text/video layout.
Deploying to Cloudflare Pages
The site is deployed automatically via Cloudflare Pages. Any push to the main branch triggers a build.
Build settings in Cloudflare:
| Setting | Value |
|---|---|
| Build command | hugo --minify |
| Output directory | public |
| Root directory | (leave blank) |
The baseURL in hugo.toml is already set to the live domain:
baseURL = 'https://ben.white-wells.com/'
Quick Reference
| Task | What to do |
|---|---|
| New engineering post | Create .md in content/engineering/ |
| New blog post | Create .md in content/posts/ |
| Add gallery photo | Drop image into assets/images/gallery/ |
| Add a static image | Drop into static/images/ |
| Change nav menu | Edit [menu] in hugo.toml |
| Change posts per page | Edit paginate in hugo.toml |
| Custom CSS tweak | Edit static/css/custom.css |
| New page layout | Create layouts/_default/name.html, set layout: name in front matter |
| Set banner for a section | Use cascade in the section’s _index.md |
| Preview locally | hugo server -D |
| Build for deploy | hugo --minify |