Howto: Delimiter separated tags


#1

The construction below looks counter-intuitive, but it works:

Given:

Tags =  ['item1', 'item2', 'item3']

This:

{{ range $i, $e := .Params.tags }}{{ if $i }}, {{ end }}{{ $e }}{{ end }}

Gives:

item1, item2, item3

The example above uses tags with comma as delimiter, but this of course also applies to other ranges and delimiters.


First/Last item of iteration
Conditional behavior in template if last array item was found
[solved] Delimited complete list of taxonomy terms? (map to array?)
[Solved]Delimit map from data file
Customize Params question,I‘m new user
#2

This worked out great. The only thing I can’t figure out now is how to handle the trailing comma in a key:value map.


#3

This is a partial (array_to_sentence_string) that I translated from some code in Jekyll.

{{ $len := len . }}{{ if eq $len 1 }}{{ index . 0 }}{{ else if eq $len 2 }}{{ index . 0 }} and {{ index . 1 }}{{ else }}{{ $last := sub $len 1 }}{{ range first $last . }}{{ . }}, {{ end }}and {{ index . $last }}.{{ end }}

You use it as {{% array_to_sentence_string .Params.tags %}}. This results in:

item1, item2, and item3.

I also have partials/post/tag/list.html (in cabaret) that more closely does what you want.

{{ with .Params.tags }}
<div class="tags-list">
  <span class="dark-red">Tags</span><span class="decorative-marker">//</span>
  {{ $len := len . }}
  {{ if eq $len 1 }}
    {{ partial "post/tag/link" (index . 0) }}
  {{ else }}
    {{ $last := sub $len 1 }}
    {{ range first $last . }}
      {{ partial "post/tag/link" . }},
    {{ end }}
    {{ partial "post/tag/link" (index . $last) }}
  {{ end }}
</div>
{{ end }}

#4

I just submitted a PR with a new delimit function that handles most of these use cases in a much more readable fashion (not the and separator yet).


#5

I wanted to use the new delimiter function, but I don’t know how to add link around tags. Is it possible ?

In the meantime, the solution provided by @bep at the beginning of this thread works fine. So thanks for that. :slight_smile:


#6

It is possible, but it is a little…unconventional. You have to apply around. This is what I use in cabaret for my tag list.

<!-- layouts/partials/post/tag/list.html -->
{{ with .Params.tags }}
<div class="tags-list">
  <span class="dark-red">Tags</span><span class="decorative-marker">//</span>
  {{ $sort := sort . }}
  {{ $links := apply $sort "partial" "post/tag/link" "." }}
  {{ $clean := apply $links "chomp" "." }}
  {{ delimit $clean ", " }}
</div>
{{ end }}

This block:

  1. Sorts .Params.tags and assigns it to $sort.

    sort .Params.tags => sort [ c, a, b ] => [ a, b, c ]
    
  2. Applies the function partial over the elements of $sort and assigns the resulting list to $links. The partial function is given post/tag/link as the name of the partial to use, and "." is the placeholder for the current element during function application.

    apply [ a, b, c ] "partial" "post/tag/link" "." => [
      partial "post/tag/link" "a",
      partial "post/tag/link" "b",
      partial "post/tag/link" "c",
    ] => [
      <a class="post-tag post-tag-a" href="/tags/a">a</a>\n,
      <a class="post-tag post-tag-b" href="/tags/b">b</a>\n,
      <a class="post-tag post-tag-c" href="/tags/c">c</a>\n,
    ]
    
  3. Removes the trailing \n from each resulting link in $links by applying chomp over the elements and assigning it to $clean.

    apply [ <a…>a</a>\n, <a…>b</a>\n, <a…>c</a>\n ] "chomp" "." => [
      <a class="post-tag post-tag-a" href="/tags/a">a</a>,
      <a class="post-tag post-tag-b" href="/tags/b">b</a>,
      <a class="post-tag post-tag-c" href="/tags/c">c</a>,
    ]
    
  4. Creates a single result by delimiting $clean with ", "; this is inserted as the tag list.

    delimit [ <a…>a</a>, <a…>b</a>, <a…>c</a> ] ", " =>
        "<a…>a</a>, <a…>b</a>, <a…>c</a>"
    

Like I said, it’s a little unconventional, and it requires a little bit of preparatory work to make it sensible, but it’s quite powerful.

<!-- layouts/partials/post/tag/link.html -->
<a class="post-tag post-tag-{{ . | urlize }}" href="/tags/{{ . | urlize }}">{{ . }}</a>

[solved] Delimited complete list of taxonomy terms? (map to array?)
#7

Well, indeed, it’s not conventional… :smiley:

Don’t you think there should be an easy way ? A function that would output directly a list of taxonomy and links. Maybe I should open a feature request for that.

Thanks anyway for taking the time to explain your method !