Feedback wanted: Nested sections: Content structure

See https://github.com/spf13/hugo/issues/465

I’m starting to think about finishing my thoughts on this and add an implementation.

I would like some feedback on content organisation.

I have created a suggested outline below:

▶ tree content
content
└── blog
    ├── _subsection1
    │   └── first-subpost.md
    ├── first-post.md
    ├── second-post.md
    └── third
        └── index.md

It shows existing structures that we must not mess with and a suggested way to add more levels.

It isn’t fantastic pretty, but I assume that prefixing with “_” should eliminate most collisions.

Looks good? Any other ideas?

2 Likes

Looks good to me.

Here are my questions.

Are we getting a default nested-list.html or will nested sections still refer to list.html ?

Will there be a NestedSection variable?
For use in templates like {{if eq .NestedSection "some-nested-section"}} ?

Same question for pagination? Will there be a .NextInNestedSection or will NextInSection be good enough? (same for Prev)

Thanks for your effort.

I was hoping to ask one focused question and not get tangled into all sorts of problem, but here is how I see it:

  • A section is a section so there will not be any “NextInNestedSection”.
  • I do not plan to do anything about the template naming scheme unless someone come up with a great idea. What we have covers most use cases – and it would be good to test it out before we add more stuff.
  • We have a .Section variable that I assume will, for the subsection1 example above, contain “blog/subsection1”
  • We have also a unexported sections field which we may export, which would be handy to use to build navigation etc., that is a string slice and would in the example above contain `[“blog”, “subsection1”]``
  • Also note that to get a specific subsection, the syntax would be {{ $subsection := .Site.GetPage "section" "blog" "subsection1" }}
1 Like

Sorry to bombard you with questions. But I had to know.

No need to add template variables, if we have access to this:

That’s all we need.

Again thank you. This is a very important feature for Hugo.

As far as I understand, the basis for the Hugo is a simple idea - the URL structure must match the folder structure. I think this is the right idea. It looks strange that we need to add characters to the folder names for copying the folder structure.

That’s for backwards compatibility. You can’t expect him to rewrite huge chunks of the existing Hugo engine.

It seems to me that by default Hugo must copy files as is. For generating a list of files for a subsection, it must use the directive in the front matter. If this is certainly possible to implement.

1 Like

I see no problem implementing this, and I see no good way around it. We need an easy way to distinguish sections from “regular folders”.

For the symmetry of it, I would say that both of the below should work:

▶ tree content
content
└── blog
    ├── _subsection1
    │   └── first-subpost.md
    ├── first-post.md
    ├── second-post.md
    └── third
        └── index.md
▶ tree content
content
└── _blog
    ├── _subsection1
    │   └── first-subpost.md
    ├── first-post.md
    ├── second-post.md
    └── third
        └── index.md

And note that this is not about backwards compability. We really need a non-ambigous way to handle this.

  1. We have taxonomies (terms and list), which we can identify because they are specified by the user in front matter / site config.
  2. We have the first directories below /content (i.e. /content/blog) which is always a section if it is not a taxonomy.
  3. Then we have the other regular directories where the user chooses to “put stuff in”
  4. Then we have sub-sections.

I suspect that 3) will evolve into “bundles” at some point, but right now we need to handle case 4).

1 Like

Makes sense to me.

:thumbsup:

I like any functionality that moves away from a model where menus are reliant on specifying navigation/relationships in front matter. (I don’t think IA matters need to travel with a document.)

Also awesome, in addition to your other thread w/r/t .GetSection.

The following can be tabled or put into another thread if it’s out of scope:

  1. Using your example, will .Data.Pages in layouts/section/blog.html access 4 .md or only the two posts?
  2. If a layout is not specified/created at layouts/third/list.html, will your content file at blog/third/index.md (or, rather, _index.md), then look for layouts/blog/list.html next? If so, you wouldn’t need the underscore, correct? That is, since a directory in a section currently follows the lookup of the parent directory (i.e., the .Section) unless a user specifies a type in the front matter, which would override the location of the file anyways…

This is a really cool feature. I’m stoked. Thanks, @bep!

1 Like

@rdwatters “third” isn’t a section. If I don’t get any clever ideas, template lookup will behave exactly like today, we may refine later. If you look in the documentation and replace SECTION with “blog/subsection1” you should get the idea.

1 Like

I simply don’t like the leading underscore idea. It’s not intuitive and is too limiting.

Alternative: Support Standalone Metadata Files In Content Dir

One of the ideas from @spf13’s “Hugo Next” brain dump was supporting a metadata.toml file inside of a directory so that you could separate the page metadata from the content file(s). We could extend that idea to sections, whereby, if we find a metadata.toml file with type = section (or something) defined, we treat that node in the content tree as a subsection. It also allows us to add metadata about the subsection itself (if that would be helpful).

▶ tree content
content
└── blog
    ├── subsection1
    │   └── metadata.toml
    │   └── first-subpost.md
    ├── first-post.md
    ├── second-post.md
    └── third
        └── index.md
1 Like
  • How is it limiting?
  • How is it more intuitive to put a metadata.toml file with some configuration variables in it? Both need documentation, the “_” is, I would say, easier to document than the TOML file. Not?

@moorereason note that I’m not saying that what you say does not makes sense – but it would be nice with arguments beyond “I don’t like it”.

If we go the metadata way, I would say that a more natural fit would be to put it in “_index.md”.

But looking ahead, I see 3 different types of directories:

  1. Sections (including the nested)
  2. Just regular directories (as a logical way of managing 1000s files)
  3. Bundles

The first 2 are kind of booleans – either or, and I would not need more than a flag (say, a “_” prefix) to determine.

For 3) I would probably also need some additional metadata, but not necessarily in its own file (aka. metadata.toml); if a bundle always contain 1 content file, why not configure the bundle in that?

My main point is, I don’t know enough about bundles to commit to any design.

  • Adding a new config file now and see that it’s not needed 3 versions from now, would be bad.
  • Adding a naming convention now and see that it is superfluous 3 versions from now, would be liveable.

I agree with this. _Index.md is more convenient for a folder, because it allows to have content and metadata.

it would be nice with arguments beyond “I don’t like it”.

Sorry, I was tired and in a hurry, so I skipped the “why” part.

How is it limiting? not intuitive?

I agree that the underscore prefix is simple, but…

We essentially ban the use of underscore-prefixed directory names. How do we add metadata for the subsection? Do we deviate from how we define metadata for other content (which is also an argument against metadata.toml)?

a more natural fit would be to put it in “_index.md”.

Agreed! I’m in favor of this approach. :+1:

But looking ahead, I see 3 different types of directories: …

I agree with everything you said in this section.

As a general principle, I think we should avoid reserving any additional path names if we can, esp. naming patterns like “any directory with a leading underscore.” We need really good arguments for reserving more names/patterns, and I don’t think this case is a good one. And as you pointed out, we don’t have a good argument for reserving metadata.toml at this point either.

1 Like

OK, this actually makes the implementation simpler as well.

So:

Any _index.md below content marks that directory as a section … if it is not a taxonomy …

Note about the above:

  • The first directory will still be a section even if it has no _index.md (i.e. blog, posts etc, like today)
  • We don’t add any metadata, but this opens up for other interpretations later, i.e. bundles.
2 Likes

This makes solid sense to me and doesn’t add another gotcha with an underscore.

@bep this is about content structure, but that also has to do with type inheritance w/r/t sections. In your example above, does third/index.md assume a type of third or blog? Does subsection assume a type of _subsection or blog?

If it’s possible, I wouldn’t recommend adding complexity to the lookup order. So, for example, if first-subpost.md assumes a type of subsection (unless otherwise specified in the front matter), the lookup order is still…

  1. /layouts/<TYPE>/<LAYOUT>.html
  2. /layouts/subsection/<LAYOUT>.html
  3. /layouts/<TYPE>/single.html
  4. /layouts/subsection/single.html
  5. /layouts/blog/<LAYOUT>.html
  6. /layouts/blog/single.html
  7. /layouts/_default/single.html

…repeat for themes…

Or is…

…replacing #2 and #4 above but still piping in the parent layouts in the order?

What? As I said, “third” is just a “regular folder”, i.e. not a section. But we have had people who have used this as a “poor man’s bundle”, hence the index.md – there were some shouting about me breaking that pattern a month ago…

And as I said, this is not a discussion about template lookup orders. We may improve on that, but there is a thing called “doing one thing at a time”.

Yes, I remember this. “Type inheritance” sounds too programmerish in this case. What I meant was Hugo assuming that a .md file’s type is equal to .Section unless otherwise specified in the front matter and whether this assumption would carry over for the nested section as well. But the idea of _index.md == section makes sense and kind of answers this already.

Cool. But I’m not talking about improvements as much as whether this would continue to observe the existing lookup order. And, you’re right, we can skip that part of this thread entirely :smile:

A .Section is a section, which is well defined. There is no front matter magic involved. Does the documentation say anything else?