Range pages in menu identifier for listing in summary

Hello. Can’t figure how to:

  • range all pages in “teachers” menu section (defined in config.yaml)
  • .Render “summary” for each page
{{ $menu := .Site.Menus.main }}
{{ range $index, $page := $menu }}
  {{ if eq .Identifier "teachers" }}
     {{ $url := strings.TrimSuffix "/" .URL }}
    
    /* 1) How to range menu entry with specific identifier? */
   /*  2)  When in range, .Site.GetPage appear to be useful, to find pages... 
   {{ $url := strings.TrimSuffix "/" .URL }}
  {{  $page := .Site.GetPage $url }}

/* 3 but this will be right? */
  {{ $page.Render "summary" }}

  {{ end }}
{{ end }}

Thank you

It would help to see your menu structure (the YAML file).

It seems… odd to be ranging through menu items to get pages to get content. Why not just range through the pages?

Because I have an extensive and sprawling menu (https://www.ilmosaicodanza.it) with dozens of links in different identifiers and submenus. Which forces me, after having categorized the pages I want to group, to use a weight to order them in the same sequence that the user expects (and that the customer asked me :slightly_smiling_face: )

Furthermore, having done this, I also have to filter out the pages that logically must be in a category (where maybe I need to display them in some pages, but not others); but that I don’t want to appear in the listing associated with a menu item.

So whenever there is a page to add, I have to

  • assign weights for the order I want in the menu items in the config.yaml
  • assign the weights in the frontmatter of all the involved pages, to make them appear in the right place.
  • invent a parameter and an exclusion filter to filter out any pages that belong to a certain category, but I don’t want them to appear in the listing.

Adding pages becomes a ballet I’m too lazy for.
So I came up with this code, to be written in the listing.html of the categories that interest me:

  <section>
     <h1> {{ .Title }}</h1>
     {{ $menu := .Site.Menus.main }}
     {{ $site := .Site }}
     {{ $url := "" }}
     {{ range $index, $page := $menu }}
       {{ if eq .Identifier "teachers" }}
         {{ range $page.Children }}
           {{ $url = strings.TrimSuffix "/" .URL }}
           {{ with $site.GetPage $url }}
           {{ .Render "summary"}}
           {{ end }}
         {{ end }}
       {{ end }}
     {{ end }}
   </section>

This requires to correctly use “.Identifier” in the menu, which I already have to do to have the submenus and therefore it doesn’t bother me. I cycle the url contained in a section, remove the last “/” and through .GetPage get the .Page object to be rendered in the “summary”. All done.

No longer need to dance with weights and parameters, to have the same pages appearing in the menu section, and in the same order. :+1:

N.B. Requires v0.86.0 or later

Use. pageRef instead of url in the menu definition, and you can omit identifier unless there’s a duplicate name somewhere in the menu structure.

menu:
  main:
    - name: Home
      pageRef: /
      weight: 10
    - name: Teachers
      pageRef: /teachers
      weight: 20
    - name: Teacher 1
      pageRef: /teachers/teacher-1
      parent: Teachers
      weight: 10
    - name: Teacher 2
      pageRef: /teachers/teacher-2
      parent: Teachers
      weight: 20
    - name: Teacher 3
      pageRef: /teachers/teacher-3
      parent: Teachers
      weight: 30

Then you can do:

{{ range where site.Menus.main "Name" "Teachers" }}
  {{ range .Children }}
    {{ with .Page }}
      <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
      <div class="summary">
        {{ .Summary }}
      </div>
    {{ end }}
  {{ end }}
{{ end }}

The other benefit from using pageRef instead of .Name is that you can use .IsMenuCurrent if your menu is defined in site configuration.

Thanks for tips and improvements!

Regarding pageRef, I tried using it (I have Hugo v0.111.1) but gave up because it did weird things with menu links, so I went back to using url: without investigating further.

Maybe one day I’ll change it, but for now I’m still happy with it.

I had figured out a way to have the current page highlighted, and also expand the current section in the menu, without using pageRef.

Via a menuSection parameter in the frontmatter, which contains the same .Identifier to which the page belongs.
Since the menu has two or three levels, I keep the subsections of the menu expanded by writing their .Identifier both in this frontmatter menuSection parameter.
For example in the menu I have the “dancecourse” section, inside which is the “flamenco” section. In the frontmatter of these pages in the menuSection parameter there is “dancecourse” for dance course pages, and “dancecourse.flamenco” for pages in the “flamenco” menu section. In the code that generates the menu, there is a string.Contains function to match both).

So, since in the _index pages of the categories that I list in the menu I have the menuSection parameter, I modified the code I previously published to also have a single list.html that handles all cases (“double” menuSection parameter , single, or nothing).
The code can be improved, I have avoided complicating my life with recursions that I don’t need, but for what I need it works very well and I share it in case it can be useful to someone.

	<section>
		<h1>
			{{ .Title }}
		</h1>
		<div>
			{{ .Content }}
		</div>
		<div class="list-content">
		{{- $menuSection := .Params.Menusection }}
		{{- $menu := .Site.Menus.main }}
		{{- $site := .Site }}
		{{- $url := "" }}
		{{- $sezione := ""}}
		{{- $sez0 := ""}}
		{{- $sez1 := ""}}
		{{- if $menuSection }}
			{{ if strings.Contains $menuSection "." }}
				{{ $parts := split $menuSection "." }}
				{{ $sez0 = index $parts 0 }}
				{{ $sez1 = index $parts 1 }}
				{{ range $index, $page := $menu }}
					{{ if eq .Identifier $sez0 }}
						{{ range $page.Children }}
							{{ if eq .Identifier $sez1 }}
								{{ range .Children }}
									{{ $url = strings.TrimSuffix "/" .URL }}
									{{ with $site.GetPage $url }}
										{{ .Render "summary"}}
									{{ end }}
								{{ end }}
							{{ end }}
						{{ end }}
					{{ end }}
				{{ end }}
			{{ else }}
				{{ $sezione = $menuSection }}
				{{ range $index, $page := $menu }}
					{{ if eq .Identifier $sezione }}
						{{ range $page.Children }}
							{{ $url = strings.TrimSuffix "/" .URL }}
							{{ with $site.GetPage $url }}
								{{ .Render "summary"}}
							{{ end }}
						{{ end }}
					{{ end }}
				{{ end }}
			{{ end }}
			</div>
		{{ else }}
			{{ range .Pages.ByWeight }}
			<div>
				{{ .Render "summary" }}
			</div>
			{{ end }}
		{{ end }}
	</section>

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