Can I create a content subfolder without it being considered a section?

I’m building out a blog site with Hugo, and I have a question about the content structure.

The blog will probably have a lot of pages, and so I wanted to organize posts, without creating super nested URL’s.

Example:

  • /Content
    • /Topic1
      • /SubTopic1
        • / Post.md <------ I want the URL to be /Topic1/Post
      • / _index.md <— Topic1 Page
    • /Topic2

In this case, I want the SubTopic1 Folder to be purely for organization. If I have say hundreds of posts inside Topic1, it would become unwieldy. On the other hand for SEO, I want to keep the URLs as short and concise as possible.

What’s the best way to go about this?

Update: I found that I can manually overwrite the URL in a post using frontmatter, but I’m curious if there’s a better option.

I would place everything under a 'posts` directory so that they will have the same (inferred) content type. You will need to place an _index.md file in each topic directory.

content/
├── posts/
│   └── topic-1/
│       ├── subtopic-1/
│       │   ├── post-1.md
│       │   └── post-2.md
│       ├── subtopic-2/
│       │   ├── post-3.md
│       │   └── post-4.md
│       └── _index.md <-- this is necessary for each topic
└── _index.md

Then in your site configuration do:

[permalinks.page]
posts = '/:sections[1]/:slug/'
[permalinks.section]
posts = '/:sections[1]/'

This is easier (and less error-prone) than setting the url in front matter for every page.

The result…

public/
├── topic-1/
│   ├── post-1/
│   │   └── index.html
│   ├── post-2/
│   │   └── index.html
│   ├── post-3/
│   │   └── index.html
│   ├── post-4/
│   │   └── index.html
│   └── index.html
├── favicon.ico
└── index.html

The ability to set permalinks for sections was added in the past couple of months, so I recommend using the current version (v0.117.0).

2 Likes

I forgot to prevent page collisions (run hugo --printPathWarnings to see what I mean).

Site configuration:

[permalinks.page]
posts = '/:sections[1]/:slug/'
[permalinks.section]
posts = '/:sections[1]/'

[[cascade]]
[cascade._build]
render = 'never'
[cascade._target]
path = '/posts/**/_index.md'

This produces:

public/
├── topic-1/
│   ├── post-1/
│   │   └── index.html
│   ├── post-2/
│   │   └── index.html
│   ├── post-3/
│   │   └── index.html
│   └── post-4/
│       └── index.html
├── favicon.ico
└── index.html

You can futz with with cascade target if you want section listings for each topic.

3 Likes

You could also mirror your local folder and work with symbolic links.