Storing blog posts in a git submodule?

I want to save my blog post markdown files in a git repository called my-blog-posts, then add that repository as a submodule in content. I don’t know if this is the best approach for a few reasons:

  1. The URL /blog no longer exists, which may break user expectations.
  2. menus.main in hugo.toml has to be modified to point to /my-blog-posts instead of /blog.
  3. The frontmatter of every blog post has to have type: blog because all the layouts correspond to “blog” rather than to the name of the submodule.
  4. The partial that handles filtering on taxonomies, and thus has the “remove filter and go back to the full list of blog posts” button has to be modified to point to the name of the submodule rather than the typical /blog.

These things make the site and theme significantly less modular. Is there a better way to store blog posts in a git submodule, without just naming the submodule repository “blog”?

Using modules is much easier. For example:
https://github.com/jmooring/hugo-module-content

1 Like

I settled on using git submodules in the first place because I can’t even make a Hugo module theme work, let alone content. To use a theme, I tried the following:

  1. cd mysite/themes
  2. hugo mod init gitlab.com/myname/mytheme.git
  3. Add the following to hugo.toml:
[module]
  [[module.imports]]
    path = 'gitlab.com/myname/mytheme.git'
  1. cd ..
  2. hugo mod get -u ./...
  3. hugo server

It gives the error:

Error: command error: failed to load modules: module “mytheme” not found in “\mysite\themes\mytheme”; either add it as a Hugo Module or store it in “\mysite\themes”.: module does not exist

What’s the problem? In git you just add, init and go.

How would I make a Hugo module correspond to a subdirectory of content by a different name? Can Hugo get the lastmod of Hugo modules, since this is apparently impossible with git submodules?

Without seeing your repository I have no idea.

Is it supposed to leave only go.mod in themes, or pull down the files from the repo?

If you go with git submodule:

What’s wrong with using /content/blog as local path for the submodule?

git submodule add <repo> content/blog

If you go with hugo modules

Have look at this recent topic using replace: Hugo Modules without GitHub

1 Like

This is actually a very good way to solve my initial problem with submodule repo names not matching the intended path. Works perfectly with just a flick of the wrist. Thank you!

However, I don’t think Hugo is able to get git info like lastmod from git submodules, so I spent the past three hours trying to get them to work as Hugo modules to no avail. hugo mod vendor puts the theme files in _vendor as expected and builds/serves themed pages that are part of the site repo (i.e. content/_index.html), but cannot vendor my blog module because “need at least one mount” and does not clone or build my blog posts. What’s wrong with this mount setup?

[module]
  [[module.imports]]
    path = "gitlab.com/myname/mytheme"

  [[module.imports]]
    path = "gitlab.com/myname/myblog"

  [[module.mounts]]
    source = "gitlab.com/myname/mytheme"
    target = "themes/mytheme"

  [[module.mounts]]
    source = "gitlab.com/myname/myblog"
    target = "content/blog"

I thought Hugo mods were supposed to be simpler… :face_with_spiral_eyes:

Not very deep in modules.

For locally stored stuff you need the replace setting. Clone it outside and use replace ro map.

I would place the blog posts in content/blog of your module. Then it will be auto atically available whwn u use that as a normal theme. No mount necessary.

Not sure if gitinfo works works with themes.

1 Like

Thank you for replying. To be clear, I don’t care about storing module content locally; I was only using vendor to try to get more information about which modules were working and which were not.

How does Hugo determine that my content doesn’t actually go into theme/myblog if I don’t specify content/blog? At least as far as vendor is concerned, it is telling me my content module needs a mount despite already having specified one anyway:

[module]
  [[module.imports]]
    path = "gitlab.com/myname/mytheme"

  [[module.imports]]
    path = "gitlab.com/myname/myblog"

  [[module.mounts]]
    source = "gitlab.com/myname/myblog"
    target = "content/blog"

With or without the mount config, the theme works but the content does not. myblog isn’t downloaded when I run hugo mod get -u and isn’t stored locally when I run hugo mod vendor. Its pages aren’t built in public, it doesn’t appear anywhere on the site and links that should point to blog content instead point to the current page.

This repo contains only a handful of markdown files.

I never tried with modules on gitlab, but if you say your theme works:

expecting

  • both modules exist in gitlab
  • both are initialized as modules
  • your main site is initialized as a module
baseURL = 'https://example.org/'
languageCode = 'en-us'
title = 'My New Hugo Site'

## NO theme = ... entry 
## NO mounts

[module]
[[module.imports]]
path = "gitlab.com/myname/mytheme"

[[module.imports]]
path = "gitlab.com/myname/mytheme"

and your top-level folder of the blog module contains content/blog with all the blogs

if that does not work … maybe sharing the repo will help.

Ive not read all the details in this post.

But i use .gitmodules for my custom hugo theme, i have a couple of sites and frequently update my theme. Cant see why it wont work with content

Create a .gitmodule in your project

[submodule "content"]
	path = content
	url = https://github.com/<username>/my-blog-posts-repo.git

Take a look at the repo: GitHub - andreasbalevik/hugo-fjordapartments.com: hugo-fjordapartments

I build all my sites on Netlify, and it fetches the submodules automatically.