Building content from multiple repositories?

Hello,

I’d like to know whether Hugo offers a way to build content from multiple repositories. For example, if content that was once in /content/{subfolder1}, /content/{subfolder2}, … should be moved to separate repositories for each, can we build a site by aggregating content from those repositories?

I was not convinced whether Hugo Modules is fully suitable for this along with our requirements, because of the following:

  • It seems that Hugo Modules do not provide a way to break down the dependencies of content further to more granular level.
  • There will not be tagging/versioning on each content repository, because of management overhead.

In case of MkDocs, there is a ‘monorepo’ plug-in (somewhat misleading name, I suppose) for this purpose. I’m curious if there’s a similar built-in feature for this in Hugo.

And if there is, I’d be more than grateful if you could share an example site/repository.

  • Yes, you can import any number of repositories and mount the source folders anywhere you want (e.g. content/subfolder1)
  • You don’t need to tag/version, but you need to do a hugo mod get -u to pull in the latest.

Thank you, @bep. I’ll have to study Hugo Modules and Go Modules more carefully,

I have an additional question regarding the combination of this topic and i18n, so I’ll create another thread.

It’s my new setup after finally taking the time to understand Hugo Modules.

Although my /content/ is just one repository, my folders are separate.

My content repo is: GitHub - YourOnly-One/youronlyone-hugo-content: Content in YourOnly.One.
with subfolders for different blogs – /snoworld/, /yuki/, and so on.

My hub blog /yuki/ pulls content from all subfolders in that repo (you can see it in action: YOOki Chronicles)

Another thing, I have multilingual support.

This is my [module] code in my config.toml file:

[module]
	replacements = [
		"github.com/YourOnly-One/youronlyone-hugo-defaults -> /home/yuki/repos/hugo-modules/youronlyone-hugo-defaults",
		"github.com/YourOnly-One/hugo-structured-data -> /home/yuki/repos/hugo-modules/hugo-structured-data",
		"github.com/YourOnly-One/hugo-shortcodes -> /home/yuki/repos/hugo-modules/hugo-shortcodes",
		"github.com/YourOnly-One/hugo-atom-feed -> /home/yuki/repos/hugo-modules/hugo-atom-feed",
		"github.com/g1eny0ung/hugo-theme-dream -> /home/yuki/repos/hugo-themes/hugo-theme-dream",
		"github.com/YourOnly-One/youronlyone-hugo-content -> /home/yuki/repos/hugo-modules/youronlyone-hugo-content"
	]

	[[module.imports]]
		disable = false                           # default: false
		ignoreConfig = false                      # default: false
		ignoreImports = false                     # default: false
		noMounts = false                          # default: false
		noVendor = false                          # default: false
		path = "github.com/YourOnly-One/youronlyone-hugo-defaults"
	[[module.imports]]
		path = "github.com/YourOnly-One/hugo-structured-data"
	[[module.imports]]
		path = "github.com/YourOnly-One/hugo-shortcodes"
	[[module.imports]]
		path = "github.com/YourOnly-One/hugo-atom-feed"
	[[module.imports]]
		path = "github.com/g1eny0ung/hugo-theme-dream"

	[[module.imports]]
		path = "github.com/YourOnly-One/youronlyone-hugo-content"

		# BGN: /yuki/ content
			#[[module.imports.mounts]]
			#  source = "yuki/eng-ph"
			#  target = "content"
			#  lang = "en"
			[[module.imports.mounts]]
				source = "yuki/eng-ph"
				target = "content"
				lang = "en-ph"
			[[module.imports.mounts]]
				source = "yuki/nihongo"
				target = "content"
				lang = "ja"
			[[module.imports.mounts]]
				source = "yuki/hangugeo"
				target = "content"
				lang = "ko"
		# END: /yuki/ content

		# BGN: /snoworld/ content
			#[[module.imports.mounts]]
			#  source = "snoworld/eng-ph"
			#  target = "content"
			#  lang = "en"
			[[module.imports.mounts]]
				source = "snoworld/eng-ph"
				target = "content"
				lang = "en-ph"
			[[module.imports.mounts]]
				source = "snoworld/nihongo"
				target = "content"
				lang = "ja"
			[[module.imports.mounts]]
				source = "snoworld/hangugeo"
				target = "content"
				lang = "ko"
		# END: /snoworld/ content

		# BGN: /love/ content
			#[[module.imports.mounts]]
			#  source = "love/eng-ph"
			#  target = "content"
			#  lang = "en"
			[[module.imports.mounts]]
				source = "love/eng-ph"
				target = "content"
				lang = "en-ph"
			[[module.imports.mounts]]
				source = "love/nihongo"
				target = "content"
				lang = "ja"
			[[module.imports.mounts]]
				source = "love/hangugeo"
				target = "content"
				lang = "ko"
		# END: /love/ content

		# BGN: /way/ content
			#[[module.imports.mounts]]
			#  source = "way/eng-ph"
			#  target = "content"
			#  lang = "en"
			[[module.imports.mounts]]
				source = "way/eng-ph"
				target = "content"
				lang = "en-ph"
			[[module.imports.mounts]]
				source = "way/nihongo"
				target = "content"
				lang = "ja"
			[[module.imports.mounts]]
				source = "way/hangugeo"
				target = "content"
				lang = "ko"
		# END: /way/ content

		# BGN: /techmagus/ content
			#[[module.imports.mounts]]
			#  source = "techmagus/eng-ph"
			#  target = "content"
			#  lang = "en"
			#[[module.imports.mounts]]
			#  source = "techmagus/eng-ph"
			#  target = "content"
			#  lang = "en-ph"
			#[[module.imports.mounts]]
			#  source = "techmagus/nihongo"
			#  target = "content"
			#  lang = "ja"
			#[[module.imports.mounts]]
			#  source = "techmagus/hangugeo"
			#  target = "content"
			#  lang = "ko"
		# END: /techmagus/ content

	# See: https://gohugo.io/hugo-modules/configuration/#module-config-mounts
	#   if you add a mounts section you should remove the old staticDir etc. settings.
	#   When you add a mount, the default mount for the concerned target root is ignored: be sure to explicitly add it.
		#[[module.mounts]]
		#  source = "content/eng-ph"
		#  target = "content"
		#  lang = "en"                                # when in multihost / multilang mode
		[[module.mounts]]
			source = "content/eng-ph"
			target = "content"
			lang = "en-ph"                             # when in multihost / multilang mode
		[[module.mounts]]
			source = "content/nihongo"
			target = "content"
			lang = "ja"                                # when in multihost / multilang mode
		[[module.mounts]]
			source = "content/hangugeo"
			target = "content"
			lang = "ko"                                # when in multihost / multilang mode

		#[[module.mounts]]
		#  source = "static/eng-ph"
		#  target = "static"
		#  lang = "en"                                # when in multihost / multilang mode
		[[module.mounts]]
			source = "static/eng-ph"
			target = "static"
			lang = "en-ph"                             # when in multihost / multilang mode
		[[module.mounts]]
			source = "static/nihongo"
			target = "static"
			lang = "ja"                                # when in multihost / multilang mode
		[[module.mounts]]
			source = "static/hangugeo"
			target = "static"
			lang = "ko"                                # when in multihost / multilang mode

		[[module.mounts]]
			source = "layouts"
			target = "layouts"
		[[module.mounts]]
			source = "data"
			target = "data"
		[[module.mounts]]
			source = "assets"
			target = "assets"
		[[module.mounts]]
			source = "i18n"
			target = "i18n"
		[[module.mounts]]
			source = "archetypes"
			target = "archetypes"

As you can see, you can use Hugo Modules for all 7 default folders of Hugo, even i18n folder. It is possible to have a central i18n files which contains global translations for each language, then a separate file for theme-specific translations or /i18n/ folder residing in your usual Hugo project folder. Hugo will merge it together: /project/i18n/en.toml + /module/i18n/en.toml. (This is what I’m going to do today for my sites.)

Notes:

  • I use replacements so I can use my local copy of my repo which makes building the site faster. I think this affects both hugo server and hugo, so if you are sharing your project’s repo with someone else, it’s advisable to comment it out (or use a separate config file for dev, see: Configure Hugo | Hugo)

  • If you have a multilingual site and you were using the lang-subfolder method (see: Multilingual Mode | Hugo), you can remove contentDir per language after setting up your [[module.mounts]] (see above, it should be per language subfolder). I’m not sure if there’ll be a conflict but on my limited testing, it was ignored in favour of the modules setting.

In your case, you can have something like this for your /content/ (with multilingual “Translation by content directory” support):


	# sample repo with content in the root of repo
	[[module.imports]]
		path = "github.com/username/content1"
		#[[module.imports.mounts]]
		#  source = "eng-ph"
		#  target = "content"
		#  lang = "en"
		[[module.imports.mounts]]
			source = "eng-ph"
			target = "content"
			lang = "en-ph"
		[[module.imports.mounts]]
			source = "nihongo"
			target = "content"
			lang = "ja"
		[[module.imports.mounts]]
			source = "hangugeo"
			target = "content"
			lang = "ko"

	# sample repo with content in /content2/ subfolder
	[[module.imports]]
		path = "github.com/username/reponame/content2"
		#[[module.imports.mounts]]
		#  source = "content2/eng-ph"
		#  target = "content"
		#  lang = "en"
		[[module.imports.mounts]]
			source = "content2/eng-ph"
			target = "content"
			lang = "en-ph"
		[[module.imports.mounts]]
			source = "content2/nihongo"
			target = "content"
			lang = "ja"
		[[module.imports.mounts]]
			source = "content2/hangugeo"
			target = "content"
			lang = "ko"

Shalom!

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.