Render some pages only in non production

Hello, I have some .md pages that may occur at all levels in a content folder, alongside regular content.

I want these pages to act like regular pages only in “development,” but not in “production.”

I am reviewing these pages in the documentation but still can not find the answer.



Edit: I believe I could add specific front-matter to these pages to help (type: "development"), but this would mean adding a filter to many list functions across multiple templates.

I think I was hoping for an option like

_build:
  list: "development"
  render: "development"

Solved

Update: I marked this as the solution for three reasons.

  1. It currently works.
  2. It would transition easily to ideal solution if issue mentioned is resolved.
  3. Avoids maintaining a separate structure. There was a core requirement to have the internal pages alongside existing content.

Thanks for all the responses!

I think, this particular section from the documentation can help you : Configure Hugo | Hugo (gohugo.io).

Thanks, I understand I can have a custom config for staging or production. But I don’t understand how I would tell hugo not to bother with some pages in production only.

Can you name the files to skip with a consistent pattern? For example:

content/something/foo.skip.md
                      ----

INMHO, this sounds quite vague.

Here is one approach:
Let’s say, you have 3 sections: sec1, sec2, sec3 and you have the following structure for config files:

├── config
│   ├── _default
│   │   ├── config.toml
│   ├── production
│   │   ├── config.toml
│   └── staging
│       ├── config.toml

1st you should make use of site.Params.mainSections in your template.
2nd specify different mainSections for each of the config.toml files.

For example, say you have the following in production/config.toml:

[params]
mainSections = ["sec1"]

Then Hugo should bother about sec1 in production environment.

This is a viable option. Could you elaborate on how I tie this into the build?

In site config:

[[cascade]]
[cascade._build]
list = 'never'
render = 'never'
[cascade._target]
environment = '{production}'
path = '**.skip.md'

You can target path, kind, lang, and environment… but not type. Hence the need for some consistent pattern in the path.

It would be convenient if we could target type:
https://github.com/gohugoio/hugo/issues/10936

1 Like

My content folder exists with many section and subsections - nested leaf and branch bundles. Most files I want in production. However, some files which exist in parallel to production content files I only want in development.

It appears that _index.skip.md no longer functions as list page the same as _index.md. Is there a way I can return this functionality?

Are you trying to skip the entire section?

The example above works with regular content pages, not leaf or branch bundles. You could consider including the string “_skip_” somewhere in the path other than the file name, but… yuck.

To do this right would need:
https://github.com/gohugoio/hugo/issues/10936

Yes exactly. I want to skip some leaf bundles and branch bundles. However I still want the branches to act as expected.

├── section_a
│   ├── _index.md
│   ├── _skip
│   │   ├── _index.skip.md
│   │   ├── skip_a
│   │   │   ├── index.skip.md
│   │   ├── skip_b
│   │   │   ├── index.skip.md
│   ├── content_a
│   │   ├── index.md
│   ├── content_b
│   │   ├── _index.md
│   │   ├── sub_b_one
│   │   │   ├── index.md
│   │   │   ├── index.skip.md
│   │   ├── sub_b_two
│   │   │   ├── index.md

Yeah I think this is it! type = "internal" sounds great.

I am OK with using _skip_ as a folder name. But I still do not understand how I would edit this config. I apologize if this is obvious.

[[cascade]]
[cascade._build]
list = 'never'
render = 'never'
[cascade._target]
environment = '{production}'
path = '**.skip.md'

To get an idea of scope:

  • Approximately how many content pages?
  • Approximately how many need to hidden in production?

Napkin math:

Currently my site has only ~200 pages. It will likely never exceed 5,000. It appears I currently may require a .skip solution ~10%.

OK, for the record:

  • I hate this
  • I wouldn’t do it
  • I would wait to see if #10936 is accepted and implemented.
content/
├── posts/
│   ├── foo-skip/
│   │   ├── foo-1-skip.md
│   │   ├── foo-2.md
│   │   └── _index.md
│   ├── post-3-skip/
│   │   └── index.md
│   ├── post-1.md
│   └── post-2-skip.md
└── _index.md
[[cascade]]
[cascade._build]
list = 'never'
render = 'never'
[cascade._target]
environment = '{production}'
path = '{**-skip.md,**-skip/index.md,**-skip/_index.md}'

But I just had another idea that might work for you. Give me a few…

An alternative… still not ideal. But maybe easier to keep track of the “internal” docs.

To build on @Sid’s suggestion, we can use an environment-specific configuration combined with a directory mount.

content structure

content/
├── posts/
│   ├── foo/
│   │   ├── foo-1.md
│   │   └── foo-2.md
│   ├── post-2/
│   │   └── index.md
│   ├── _index.md
│   └── post-1.md
└── _index.md

content-internal/
└── posts/
    ├── foo/
    │   └── _index.md
    ├── post-4/
    │   └── index.md
    └── post-3.md

site configuration

config/
├── _default/
│   └── config.toml
└── development/
    └── config.toml

config/development/config.toml

[[module.mounts]]
source = 'content'
target = 'content'

[[module.mounts]]
source = 'content-internal'
target = 'content'

The content-internal directory will be included when running hugo server or hugo -e development.

1 Like

Maybe I’m mistaken, but could you not use the draft: true frontmatter property ?
Building with --buildDrafts option when in developpment ?

Good point, yes, I can achieve a similar outcome by using drafts or date-hacking with --buildsFuture. However, I would then lose the ability to use drafts (or dates) for their intended purpose.

Thinking more about this, targeting pages based on type in front matter is not a good idea, at least for your particular use case—it would preclude you from using type to control which layout is used.

The right way is to target based on a custom front matter parameter, which may not be possible—it seems like front matter parameters are not available until after we cascade front matter parameters down from site configuration (chicken/egg).

I will edit #10936, but don’t be surprised if this is closed as either not possible or too expensive (time and/or performance).

As for what’s possible today, mounting an additional content directory based on environment (as described above) seems like the cleanest approach.

OK thanks,

Current tagged solution is working except for the case of having an internal page alongside a leaf (shown below).

content/
├── posts/
│   ├── foo/
│   │   ├── index.md
│   │   ├── notes-skip.md