Recursion in hugo

To teach myself hugo, I wrote a “Table of Contents” generator which recursively traverses the /content directory. My code looks like so:

<section>
  
{{ template "pagination" (dict "dir" .Site.Home.Pages) }}

{{ define "pagination" }}
  <ol>
  {{ range .dir }}
    {{ if (eq .BundleType "branch") }}
        <li><a href="{{ .RelPermalink }}">{{ .Title }}</a>
        {{ template "pagination" (dict "dir" .Pages) }}
        </li>
    {{ else }}
      <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
    {{ end }}
  {{ end }}
  </ol>
{{ end }}

</section>

One of the things I really struggled with as a newbie was how to write a recursive function such as the above, and I ended up relying heavily on the breadcrumb example in Content Sections | Hugo

I’d be interested in hearing from more experienced Hugo coders on whether my beginner code above is good or not.

Your “beginner code” taught me that using template and define makes actually sense in some parts. I would have done the same, but by using a partial that calls itself*. The single advantage of that approach would be that you can add it to more than one location in your website with one line, instead of having to copy the whole define section around.

* everything between define and end in layouts/partials/pagination.html and then calling instead of template to partial "pagination.html" (dict ...).

1 Like

Does Hugo have a head tail to use with this or perhaps a while .Pages equivalent? I would love to see this paired with something like either of those to split X off a subset of a .Pages collection recursively so I can pass a chunk of 2,3,or 4 pages until there are no more.

Right now I’ve found I can do it through Ranging through a .Paginate and passing that but that doesn’t seem correct. I’ve also used a seq first after and some Math to run it through but that is slower than .Paginate

I think you should start with a simpler example like this.

Then you can address the issue of a dictionary as a parameter :wink:

Hugo has ‘first n’ and ‘last n’ functions available in shortcodes.

{{ template "pagination" (dict "dir" .Site.Home.Pages) }}

{{ define "pagination" }}
  <ol>
  {{ range .dir }}

I’m new to hugo. I assume that the “dir” entry in the dictionary argument to the template is what is being picked up in
range .dir

Where is the documentation for this very useful feature? AIUI, normally one has to .Get an argument, either as a named or positional parameter. Does this not apply in the case of a map argument?