Have a read and let me know by commenting here or opening an issue on the separate repo there if you have any suggested changes or problems. After some review time I will submit this as a PR to the tutorials section if it seems useful to enough people. I confess I was super excited to have found out this is possible—especially after reading others challenges with this same thing in the forums.
Trade Offs:This is where the
where function would
come in really handy, if it worked. Unfortunately it, along with
all the grouping functions don’t work with .Site.Data
I don’t see why where shouldn’t work fine for site.Data. If it doesn’t, create a bug on GitHub.
Well I think I have this is worded in a way that implies it is a bug when it really isn’t. The following just isn’t possible because, as far as I can tell, where only works with lists and not maps:
{{ range where .Site.Data.person "admin" "in" "roles" }}
{{ partial "person/li" . }}
{{ end }}
I image there is a way to break out a sub range or pipeline but at that point it is just easier to put in the if on its own:
{{ range .Site.Data.person }}
{{ if in .roles "admin" }}{{ partial "person/li" . }}{{ end }}
{{ end }}
I misunderstood the following initially to work on maps, which I am reading in the forums is a common error:
Functions | Hugo description of where when used with the in operator specifically:
It can also be used with an operator like !=, >=, in etc. Without an operator (like above), where compares a given field with a matching value in a way like = is specified.
Thanks for looking into it. I will just remove that part.
In your tutorial you have at least one broken link. For example, you link to “https://gohugo.io/extras/data-files” in the text “Make sure you understand the data file concept fully to get the most out of it. It is really amazing.”. But the link should really be “http://gohugo.io/extras/datafiles/” (note the trailing slash).
Backticks here won’t do what you mean in most (if not all) unix shells: it would try to run the command “layouts/partials/person” and use it’s standard output as the argument to mkdir.
I can see the case for trailing slashes and do understand that links without them are essentially redirects. I also only previewed this using hugo server which corrects those. I also host on GitHub and Surge where links without trailing slashes are handled without a problem. But I will change them all. On GitHub they will all be // instead of http or https, but in the final addition to gohugo.io/templates I’ll make them all relative, as all of the other tutorials do.
I understand the meaning of back ticks, thanks for catching that. It was a dubious markdown typo essentially because I had been using back ticks for markdown every other place that path appears.
@bep how do you feel about the following explanation about where?
Beware: Where will not work here because, and let’s emphasize this, “where only works on lists, taxonomies, terms, and groups”. .Data.Pages is a list so it works. The way we have organized our data/person files means .Site.Data.person is a map, not a list.
The way where works is that the second parameter is a property of the first’s elements. So, in your example, I would expect to see the reverse of what you posted:
where .Site.Data.person "roles" "in" "admin"
However, that construct reverses the parameters on in. ["admin","user"] is not in "admin". What you need here is to be able to use intersect as an operator, which is not currently supported. That’s another Github feature request.
Two options if intersect becomes a where operator:
intersect only supports arrays/slices at the moment, and you can’t create arrays/slices on the fly in templates (IIRC). So you would need to create a site parameter (or something) to define the roles you want to match against: admin_role = ["admin"]. Then you could do this:
where .Site.Data.person "roles" "intersect" .Site.Params.admin_role
We could extend the intersect func to allow taking a single-element parameter (like a string) and treating it as a single-item array/slice (depending on the type of the other parameter):
range where .Site.Data.person "roles" "intersect" "admin"
Yet another feature request. Not clear to me yet how much that would complicate the intersect func though.