Migration from single content files to Hugo page bundles
source link: https://pawelgrzybek.com/migration-from-single-content-files-to-hugo-page-bundles/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Migration from single content files to Hugo page bundles
Published: 2023.10.05 · 2 minutes read
Since I migrated from Jekyll to Hugo a few years ago, I have never looked at any other static site generator. I elaborated on this process in “From Jekyll to Hugo! From GitHub Pages to Netlify!”. It may not be the easiest tool of its kind out there, but the complexity pays off in the form of flexibility, speed, and reliability.
Over the last few years, I have been writing and adding more Markdown files to the content pile, as well as images to the static resources folder. It was all good, but I wasn’t fully utilizing the potential of Hugo. Finally, I decided to migrate from individual Markdown files to Hugo page bundles. For those unfamiliar with this concept, the following simple diagram should help.
// BEFORE
.
├── content
│ └── posts
│ ├── 2023-10-04-post-one.md
│ └── 2023-10-05-post-two.md
└── static
├── post-one-pic-1.jpg
├── post-one-pic-2.jpg
├── post-two-pic-1.jpg
└── post-two-pic-2.jpg
// AFTER
.
└── content
└── posts
├── 2023-10-04-post-one
│ ├── index.md
│ ├── post-one-pic-1.jpg
│ └── post-one-pic-2.jpg
└── 2023-10-05-post-two
├── index.md
├── post-two-pic-1.jpg
└── post-two-pic-2.jpg
Benefits of Page Bundles#
The obvious benefit is file colocation. All files related to a single post live in the same directory. It vastly eliminates the potential for orphaned static files. When you delete a draft that you’ve lost hope for (which happens to me all the time), all related files will also be deleted. And because all links to images follow real relative paths, Markdown previews finally render correctly. A nice bonus!
Page resources is a Hugo concept where all files in a page bundle are accessible in a template via {{ .Resources }}
. They also have some extra image processing powers that are impossible with static files. This is very powerful and has allowed me to massively simplify how I handle multiple file formats (jpg
, webp
, and avif
) and dark mode variations. I have also managed to eliminate some unnecessary logic for handling open graph images—I need to remember to include an og.jpg
file in the page bundle, and Hugo will take care of the rest.
This single change doesn’t look like a lot to the visitor, but it was a massive improvement for me as a publisher. I can also reveal that I am planning to translate some of my posts into Polish, and with page bundles, it will be a breeze.
If you’re curious about how it works, the source code for my website is available on GitHub. Shout out if you have any questions or suggestions. Peace ✌️
Did you like it? Please share it with your friends or get me a
beer coffee. Thanks!
Comments#
- Dariusz Wieckiewicz2023.10.06, 12:16, #8dfe79cf
Well done Paweł. How long it took you to migrate all your posts into page bundles (roughly)? This is something on my list to do, but the time involved pushing this more and more...
- Pawel Grzybek2023.10.06, 12:41, #ba21a3c6
It was actually a very quick process. I wrote a small Node.js script that moved all the files to a new location for me. Writing the script didn't take me longer than 30 minutes, and the script execution took only a few hundred milliseconds. I would be delighted to assist you in creating a similar script if you need it. It was a fun experience 🤗
- Dariusz Wieckiewicz2023.10.06, 12:51, #fae9b098
Thanks. If you can share yours I would appreciate it. I will look and see what I can do on my site :)
- Pawel Grzybek2023.10.06, 19:53, #78b7da05
For the file structure and naming convention I followed, a simple script similar to this one did the job. Keep in mind that this is not exactly the code I used because I removed this throwaway script after I was done with it. It should be enough to give you an idea, though.
const fs = require("fs"); const PATH_POSTS = "./content/posts"; const PATH_PHOTOS = "./static/photos"; async function main() { const posts = await fs.promises.readdir(PATH_POSTS); const images = await fs.promises.readdir(PATH_PHOTOS); for (const post of posts) { const postName = post.replace(".md", ""); const postDate = post.substring(0, 10); const postImages = images.filter((image) => image.startsWith(postDate)); await fs.promises.mkdir(`${PATH_POSTS}/${postName}`); await fs.promises.rename( `${PATH_POSTS}/${post}`, `${PATH_POSTS}/${postName}/index.md` ); for (const postImage of postImages) { await fs.promises.rename( `${PATH_PHOTOS}/${postImage}`, `${PATH_POSTS}/${postName}/${postImage}) ` ); } } } main();
After that, I ran a find/replace in VSCode to amend the path for all images across all posts, and that was it. Hopefully, that helps.
- Bryce Wray2023.10.06, 15:36, #441c3f85
I am so grateful for your comment about the script that simplified this for you. I was re-bundling after briefly un-bundling, and was about to do it manually for over 300 posts scattered across five years’ worth of folders; then I saw your comment, did a mental facepalm, and realized a script was the way to go. (Only difference was that I was much lazier than you, and just prompted Google Bard to write a Bash script for me. Amazingly, it worked as prescribed, no hallucinations, no muss, no fuss.) Thanks!
Leave a comment#
👆 you can use Markdown here
Save my data for the next time I comment
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK