Node improvements

I have a specific use case in mind for enhanced nodes, or sections, and I’m trying to see if this work will allow me to implement it. Would I be able to do something along the lines:

{{ range .Data.Sections }}
    <h2>{{ .Title }}</h2>
    <img src="{{ .Params.image }}>
    {{ range .Pages }}
        ...
    {{ end }}
{{ end }}

The case is to display posts grouped by section, and have a way to attach meta-data (an image in the above case) to a section.

Yes, but not with the syntax you describe. More like:

{{ range where .Site.Nodes "NodeType" "=" "section" }}
<h2>{{ .Title }}</h2>
<img src="{{ .Params.image }}>
{{ range .Data.Pages }}

{{ end }}
{{ end }}

Which is a good example for my question above, Nodes vs Pages …

@spf13 do you have any opinions / ideas about this? Nodes, Pages … deprecation. In my head we can keep the .Data.Pages as is (it is contextual) and change the .Site.Pages to return ALL pages (including nodes etc.), which will be a mildly breaking change, but will be a clean solution.

1 Like

I tend to agree that we should deprecate .Site.Nodes in favor of everything being Pages (and .Site.Pages returns all page types). .Data.Pages is helpful, but it’s often a source of confusion for users since it’s not intuitive as to what the means (throwing out ideas: would .Context.Pages make more sense?).

I’m trying to theorize what could constitute a Node in the future. If Hugo ever added an asset or media pipeline (or other non-Page items), would those resources be considered Nodes (in the site tree)? If so, .Site.Nodes would hold every resource in a site (including Pages). Trying to think of a reason to keep hugolib.Node around at all.

1 Like

.Site.Nodes is a “new invention” (not exported in the templates) so no need to deprecate. I now agree that we don’t need it.[quote=“moorereason, post:43, topic:1593”]
.Context.Pages make more sense?
[/quote]

I don’t think so. It is an even more foreign word for the common man.

This discussion has cleared by thoughts about this, and here is how I suggest we do it for Hugo 0.18:

  • we call the spade a spade: Everything is a Page (we may keep the Node internally for a while, but that is an implementation detail, I may be to lazy to get rid of it now)
  • .Site.Pages returns all pages: Regular pages, home page, taxonomies, taxonomy terms, sections. We put this in bold text in the release notes.
  • We put the contextual page set directly below .Pages and put mild deprecation on .Data.Pages (it costs us little to keep it for a while). This is what people will try intuitively without looking in the docs.
  • We add a PageType string to Page: “page”, “home”, “section”, “taxonomy”, “taxonomyTerm”, that can be used in where to filter pages
  • We add a .GetPage(type, path...) to fetch a single page, i.e. GetPage("home), GetPage("section", "blog"), GetPage("taxonomy", "tags", "hugo") etc.

Sounds like a plan?

There will also be consequences for the .IsNode and .IsPage variables.

No, they will work as before – i.e. removing them will be too much trouble. So IsPage will indicate a regular page, and IsNode returns true on list type pages (home page, sections etc.).

They will not be as useful as before, because now that everything is a page, the templates will be more or less interoperable.

Naming

I think the naming is good, but it might get a bit confusing as to what each one actually means. For example, if you’re pointing to a node, are you pointing to the new “page” (ie, _index.md for the metadata/front matter/content) or are you pointing to all the values that are currently passed into the node, as in the current layouts/section/blog.html. Or both?

.Site Methods

This would be a great feature, but when I first read this, I guess I was thinking of it more in this way…

1.
.Site.GetPage('home')
2.
.Site.GetNode('section','blog')
3.
.Site.GetPage('section','blog','my-first-post.md')
4.
.Site.GetNode('taxonomy','tags','hugo')

Some comments/questions for each the above, numbered accordingly. I think that your examples might not have meant to be real-world use cases, too, so take it as you will:

  1. What would be the use case for grabbing a homepage? Or is this more about the workarounds people have been using to add metadata to node pages?
  2. Either in your example or in mine, would this grab content/blog/_index.md or would it be used to to put content/blog/*.md into a variable? (eg, {{$allblog := .Site.Get('section','blog')}}
  3. This would be pretty damn handy; I could see it cutting out a lot of extran range, etc in templates, and allow you to grab everything from an individual page, but what would users add to the third argument? Ie, would it be the filename, title, LinkTitle? Could they also pass a variable that’s been assigned to a piece of front matter? I can write an example template since I think what I’m writing might be confusing…
  4. Would this grab all the pages that are part of this taxonomy or were you thinking this would grab the equivalent of /tags/hugo/_index.md? Or would that be .Site.GetPage('section','blog','_index.md')?

Taxonomies

Does this mean that each taxonomy can have it’s own _index.md as well so that you can, for example, add content/descriptions to the list pages for /categories, /tags, etc? This would be tedious for folksonomies like tags, but it would be great for yoursite.com/categories or yoursite.com/authors if you only had 5-6 major categories and wanted to create a block (with description, etc) for each one. Right now, I think most people hack on data files for this type of thing.

+1 for the shift from using .Data to .Node across the board to make the distinction between nodes and the data/ folder.

Interesting use case (minus the .Data.Sections part, but @bep already touched on that ), but where would {{.Params.image}} come from? Is this something you would set in content/yoursection/_index.md?

Also…

I know this is a separate issue/request, but I wonder how these node improvements would/could affect the menu feature, since—from what I can tell on this forum—this is a feature that elicits a lot of confusion from beginners.

Lot of questions here, @rdwatters – I’m not touching everything, but i don’t think my implementation wander too far off your base, and I’m gonna stop here and not implement any further.

A couple of comments:

  1. GetPage was meant as an easy way to get a index page (not single page, that can come later, not sure how useful that is). Say you have a section named blog – fetch that section and list the lastest posts in the right margin … etc. (range (.GetPage("section", "blog").Pages) very useful. That can be done with where, too, of course, so maybe a better example would be to print the summary: (.GetPage("section", "blog").Summary or whatever.
  2. If you don’t put a _index.md in taxonomy folder etc., you still get a page for that taxonomy, but it will fall back to old defaults (as today) … I think this invites to a little careful thinking about “tagging” – but you would probably at least put one content page per taxonomy type (categories, tags).
  3. This leads to a fairly nice symmetry where every page can have params, taxonomies, be an item in a menu, have aliases etc. (most Hugo sites of today has some manually created menu items for home etc.) – and have a content file attached to it.

So when you start asking where does the .Params.image come from, ask yourself, where does that come from today? The page front matter (or the site config).

Another naming question.

I have added a new PageType field on Page that can be either page, home, section, taxonomy or taxonomyTerm.

I used PageType because Type is already taken.

But it is a mouthful:

{{ range where .Site.Pages "PageType" "section" }}

Any better suggestions floating out there?

After thinking about it I came up with the following list (in no particular order):

  • kind
  • class
  • group

Feel free to leave some feedback. Maybe do native speakers have more ideas.

1 Like

I like both kind and classkind the best I think. I think that is also used for similar stuff in the Go stdlib … If no one comes up with something even better I will stick with that one. Thanks.

1 Like

And now it it is merged into master – I would appreciate if people could take it for a spin. This is a big change, it is tested borderline paranoia, but there will be issues in the wild.

The doc is updated, but you will have to use the doc in the source.

3 Likes

Any chance for a pre-release build for Windows? I’d love to test this myself, but don’t have the infrastructure to compile from source :frowning:

Do these new changes only affect single level nesting or up to any level?

Multiple level sections has nothing to do with my changes. There is an open issue for that, but that will not be solved in Hugo 0.1.8. Please do not hijack this thread with your problem.

  1. Install Git
  2. Install Go
  3. go get -v GitHub - gohugoio/hugo: The world’s fastest framework for building websites.

The above sound just about as simple as me helping you by

  1. Compile for Windows
  2. Zip file
  3. Upload somewhere
  4. Post link to zip here

Esp. if the process have to be repeated. Having Git and Go installed is gold. You are going to thank me :slight_smile:

Nice! Looking forward to digging into this at the end of the week…thanks for all the hard work, @bep.

OK, I couldn’t resist the challenge.

I tested this oneliner:

F="hugo-0.18-pre-win"; env GOOS=windows go build -o ${F}.exe && zip ${F}.zip ${F}.exe && curl --upload-file ./${F}.zip https://transfer.sh/${F}.zip

https://transfer.sh/2CjJY/hugo-0.18-pre-win.zip

That file should be available for the next 14 days.

2 Likes

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