Ability to separate drafts into its own dedicated content folder that is environment specific?

I’m currently migrating my blog from Jekyll to Hugo. I have around 500 published posts and 300 additional drafts.

Jekyll lets you put drafts and posts into separate directories and then you can run your Jekyll server with a flag that says to include drafts or not. The idea is in development you’d enable drafts but when building your site in production you wouldn’t.

This makes it very easy to see at a glance at how many posts are live vs not. It also helps a lot when opening files because you can fuzzy find files with “drafts” in the name to immediately scope your search to only drafts. When you have hundreds of posts this makes a difference to find things.

Hugo seems to handle this differently with a draft frontmatter option but now everything is mixed together on disk in 1 directory. I didn’t see a way to split out environment specific content directories that would allow for something similar to Jekyll. Did I miss something?

You noticed the hugo flag to include/exclude drafts?

https://gohugo.io/content-management/front-matter/#cascade

content/
├── drafts/
│   ├── _index.md
│   ├── a.md
│   └── b.md
├── posts/
│   ├── _index.md
│   ├── post-1.md
│   └── post-2.md
└── _index.md

content/drafts/_index.md

+++
title = 'Drafts'
[cascade]
draft = true
+++

When you cascade a value to descendent pages, Hugo does not overwrite existing values. In the above that means that you must not set a draft value in either a.md or b.md.

2 Likes

Absolutely, but the files exist on disk in 1 spot which makes glancing and opening these files harder when they are mixed with live posts.

Would you be open to going into more detail on how the above works?

When I set things up how you describe the following things happens:

  • Going to /drafts/ renders an empty page
  • Going to /drafts/a/ with --buildDrafts renders the post
  • Going to /drafts/a/ without --buildDrafts still renders the post
  • Going to /posts/a/ throws a 404

This is much different behavior than expected. I’m hoping to achieve an outcome where /drafts/ isn’t considered content and never has a URL. Going to /posts/a with --buildDrafts would show the page and doing the same without --buildDrafts would throw a 404.

I’m not sure what you’re doing, but I suspect you’re not clearing the public directory after some of your tests. If you don’t want to publish an index page for the drafts directory, set draft to true.

Try it:

git clone --single-branch -b hugo-forum-topic-50785 https://github.com/jmooring/hugo-testing hugo-forum-topic-50785
cd hugo-forum-topic-50785
hugo && tree public

Now include drafts:

hugo -D && tree public

Now exclude drafts again, remembering to clear the public directory:

rm -rf public/ && hugo && tree public

Works great.

Yep, good call about not cleaning up old builds. After purging the old files and setting draft true on drafts/_index.md then it’s mostly working.

The only thing that’s missing now is a and b don’t show up when looping over posts on the posts index page. I’d expect the main list page for posts to include everything in posts and drafts in a way where both lists are combined and sorted as 1 unified list.

Likewise (where .Site.RegularPages "Type" "posts") is only counting posts. Maybe there’s some syntax to look for both “posts” and “drafts” here but I wonder if there’s a way to solve this so “posts” includes “drafts”.

Cascade type = 'posts'.

Wow nice thanks. That results in everything lining up.

It also duplicates /posts to /drafts so both list pages produce the same output without needing a separate layout for drafts.

I might make a case for wanting to not cascade the type in the future because having them separate is kind of useful. It’s something I never did with Jekyll so I’ll see how both methods go.

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