Sane way to delimit content in a range?

I have what feels like it should be an incredibly simple question, but I can’t figure it out.

So let’s say I have something like this in a template:

{{ with .Params.some_parameter }}
  {{ range where (where $.Site.Pages "Section" "some-other-stuff") ".Title" "intersect" . }}
    <a href="{{ .Permalink }}">
      {{ .Title }}
    </a>,
  {{ end }}
{{ end }}

…now how I do I make it so that that comma only shows up for every item except the last one in the list, without needing to do something weird like put this into its own partial?

1 Like

You can use CSS pseudo selectors for this or use a variation function on the where stagement/range. But just to make sure, can you tell me the desired output of what you want? Perhaps a repo? I see you use “intersect,” but are you trying to use the interest function here?

But just to make sure, can you tell me the desired output of what you want?

<a href="/whatever1">thing 1</a>,
<a href="/whatever2">thing 2</a>,
<a href="/whatever3">thing 3</a>

I see you use “intersect,” but are you trying to use the interest function here?

It’s intentional. I have an extremely complicated Jekyll project (4000+ pages in 20 collections referencing each other in a variety of ways, upwards of 300-second build times), and I’m looking at converting it to Hugo.

I used CSS, here for tags:

<ul class="tags">
    {{ range sort .Params.tags }}<li class="tags__tag"><a href="/tags/{{ . | urlize }}">{{ . }}</a></li>{{ end }}
</ul>

and the corresponding CSS:

.tags__tag + .tags__tag:before {
    content: ", "
}
4 Likes

The delimit function might be what you need to get this done if you don’t want to use CSS to solve the visual problem.

{{ delimit (slice "foo" "bar" "buzz") ", " }}

source: https://gohugo.io/templates/functions/ (found at apply method)

<!-- post/tag/list.html -->
{{ with .Params.tags }}
<div class="tags-list">
  Tags:
  {{ $sort := sort . }}
  {{ $links := apply $sort "partial" "post/tag/link" "." }}
  {{ $clean := apply $links "chomp" "." }}
  {{ delimit $clean ", " }}
</div>
{{ end }}
2 Likes

Thanks for the suggestion, but splitting it off into a partial is something I’m specifically trying to avoid, since that would result in 30+ slightly different partials, and that’s just from the stuff I’m converting over without considering (lots of) future work.

If there’s some way to apply delimit directly to the output of a range block without splitting it out into a partial, that would be exactly what I’m looking for.

I think that’s what @sairam is getting at: you can use his snippet in pretty much anything: a shortcode, a layout page, or a partial. If you have 30 different partials, you might be doing something wrong. OR (more likely) your site is really that complex…but 30+ partials seems like a lot…as though there might be better ways to golang template’s contextual awareness…or use content views…and partials are, by definition, more reusable than putting additional code into a single template. Maybe you can give us an example of templating you’ve actually tried or point us to a repo? I ask because your example from the original post doesn’t make sense unless you’re looking for a single page titled “intersect,” in which case you could just point that single link anywhere you want.

That said, the good news is that your site build times will increase exponentially with Hugo. It’s crazy fast :smile:

you can use his snippet in pretty much anything: a shortcode, a layout page, or a partial.

The problem is that use of apply in that way seems to depend on having a partial for generating the actual stuff in the list.

have 30 different partials, you might be doing something wrong. OR (more likely) your site is really that complex

It is that complex. The project I’m working on has a huge variety of slightly different lists—comma-separated, semicolon-separated, linking to different sections in a variety of different ways, etc.

I ask because your example from the original post doesn’t make sense unless you’re looking for a single page titled “intersect,”

It’s using the intersect operator of where to get the intersection of page titles in a given section with the values of an array parameter.

I am trying to do the same thing with $key but it shows some numbers and doesnt work

        ```<td> {{ range $key,$val := $cur }} 
                    {{ delimit ($key) ", "  }} 
                    {{ end }}</td>```

Can you suggest something?

$key will only be an actual key for structured information. It will be a numeric index if the source is an array (or slice I think in Go parlance).

For others reference, here is the code I use to produce a list of categories & tags (set in the frontmatter) for a specific page:

{{/* Show Section, Categories and Tags for this page.
   * Used in list.html>article-summary.html and single.html>meta-data.html
   * Dependencies: Bulma CSS and FontAwesome
   */}}
<br />
{{- if ne .Section .Name -}}
    <span title="Section">
        &#x1F4D6; <a href="/{{.Section | urlize }}">{{.Section | title}}</a>
    </span>
{{- end -}}
 | <span title="Categories">&#x1F4CE; 
    {{- $.Scratch.Set "l1" slice -}}
    {{ if .Params.categories }} 
        {{- range $cat := .Params.categories }} 
            {{ $t1 := (printf "<a href='/categories/%s'>%s</a>" ($cat | urlize) $cat) }}
            {{ $.Scratch.Add "l1" (slice $t1) }}
        {{- end -}}
        {{ delimit ($.Scratch.Get "l1") ", " }}
    {{- else -}}
        None
    {{- end -}}
</span>
 | <span title="Tags">&#x1F516; 
    {{- $.Scratch.Set "l2" slice -}}
    {{- if .Params.tags -}} 
        {{- range $tag := .Params.tags }} 
            {{ $t2 := (printf "<span><a href='/tags/%s'>%s</a></span>" ($tag | urlize) $tag) }}
            {{ $.Scratch.Add "l2" (slice $t2) }}
        {{- end -}}
        {{ delimit ($.Scratch.Get "l2") ", " }}
        {{ $.Scratch.Delete "l2" }}
    {{- else -}}
        None
    {{- end -}}
</span>
1 Like

Couple of changes could be made to the above. First to note that I removed the dependency on Font Awesome in the code. Secondly, you don’t really need 2 scratch variables since they are reset before each loop anyway. If you don’t reset them to an empty slice, you will get errors.

{{- if .Params.tags -}} 
    {{- range $key, $tag := .Params.tags }} 
        {{- if ne $key, 0 }}, {{ end }}<span><a href='/tags/{{ $tag | urlize }}'>{{ $tag }}</a></span>"
    {{- end -}}
{{- else -}}
    None
{{- end -}}
2 Likes