Develop and generate different site versions from a single site

I want to generate two or more versions of a Hugo site and deploy as separate sites. Ultimately I would like to be able to run one hugo server for each of the sites during development.

Just as in Create two versions of the site my initial thought was to use soft links together with --contentDir and --destination.

A better workflow would be to use a front matter field and only generate pages tagged with a certain field value, i.e., a more general version of the -D flag. Suggestions on how such a workflow can be achieved? Maybe I should make a feature request?

How does your project currently look, and what issue did you run into? Are you unable to run the Hugo server on separate ports?

@maiki - I have no trouble running multiple Hugo severs on different ports.

What I want is a way to generate multiple versions of a site by filtering the pages processed by Hugo. To filter I want to use page variables specified in the page front matter, for example a list or a boolean.

For example if I have the following content:

content/
  a.md
  b.md

Frontmatter for a.md.

+++
title = "A"
tags =  ["x", "y"]
+++

Frontmatter for b.md.

+++
title = "B"
tags =  ["y"]
draft = true
+++

What I want is way to tell Hugo to only process pages with certain value(s) for a page variable(s). I would like something like this imaginary --filter option:

hugo --filter "tags = [x]" ==> include a.md.

hugo --filter "tags = [y]" ==> include a.md and b.md.

hugo --filter "tags = [x, y]" ==> include a.md and b.md.

hugo --filter "draft = true" ==> include c.md

To make such a filter option as generic as possible boolean operators could be included, for example:

hugo --filter "draft = true && tags = [y]" ==> include c.md

hugo --filter "draft = true && tags = [x]" ==> no pages included.

Hmm, I wonder if you could set an environment variable and use getenv to test for some value in your templates, to hide or show parts of the site?

{{with getenv "BUILDTAG"}}{{.}}{{end}}

@RickCogley - Yes, but would it be possible to ignore a page altogether from within a template?

I haven’t tested it, but, I think you could probably combine getenv with a nested where?

Default might be useful to you -

You can also set a hugo config parameter as an env variable by prefixing it with HUGO_.

I’m pretty sure anything here:

Like: HUGO_ENABLEGITINFO = "true"

I assumed that as soon as Hugo started processing a page through a template, this will result in some HTML output. Hence, using where I will only be able to ignore parts of a page and not the whole page and that this will always result in a generated HTML page. But my assumption might be wrong.

True, the above would get you some content on a given page.

Spitballing here: It would be kind of jerry-rigged scripting but, you could probably take advantage of the date functions that link to switches.

I imagine you could write a script to mark one set, or another set of pages as expired.

Yes, (mis)using the flags --buildFuture, --buildDrafts and --buildExpired can be used as a workaround. I rather not use --buildDrafts for this since I use it to include/exclude draft content. This leaves me with --buildFuture and --buildExpired that can be used to generate a limited number of combinations.

You may want to look into using the multilingual feature for this. Assuming you don’t use this feature for its main purpose, you could create site1 site2 etc. as languages. It even supports multihost mode, so hugo server will spin up a server per site.

1 Like

Interesting. Can you use an arbitrary Lang code?

@bep Great idea! I will look into the multilingual features. My main concern is if this will allow for a page to belong to more than one site (language) but not belonging to another set of sites.

For my use case I will have three sites/languages (A, B & C) where the sites will have shared content and site specific content:

  • All sites A, B and C will have some content in common, i.e., sharing some content with each other.
  • A subset of the sites will have some content in common, for example site A and site B will share some content and site B and C will share some content.
  • Some content will be specific to each site.

@bep I’ve been reading about the multilingual features but I still wonder if I will be able to share content between my “languages” or if I’m better of using soft links?

I do something like that. For instance, I have a list of books, shared between two sites, which themselves have their own unique content. But I don’t serve them from the same Hugo project. Instead, I just keep content sections in their own git repos, and pull in the ones needed for any site.

Let’s say I was doing a media library (just pages about books and games). Content might look like:

content/
├── albums
├── blog
├── books
├── games
└── movies

I’d keep each of those directories in content in their own repo. Then say I want to run a second site, same content for most of those, but a different take on the blog: I pull in all those repos, but use a new blog repo specific to the site.

I think a popular method is using git submodules, and you can search for other posts about practices for that.

1 Like

I am looking into doing something similar to you. Were you able to figure out if all the content needs to be shared to all languages? For example, I want one language to have page A and page B, but the other language should only have page A.

I never put in enough effort to figure out if and how the multilingual features could be used for my use case. Instead I used a single git repo with two Hugo sites and soft links to share content between the sites.