8

Migration from single content files to Hugo page bundles

 11 months ago
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.
neoserver,ios ssh client

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!

Markdown preview in Visual Studio Code correctly renders images

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 Wieckiewicz
    2023.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 Grzybek
      Pawel Grzybek
      2023.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 Wieckiewicz
        2023.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 Grzybek
        Pawel Grzybek
        2023.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 Wray
    2023.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#

Name:
Website (optional):
GitHub (optional):
Comment:

👆 you can use Markdown here

Save my data for the next time I comment


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK