In the <pre> block it correctly prints what I expect but I’m having trouble working out how to map the count to a weight. I had a look at Drupal’s implementation but it uses min(), max(), log() and floor() functions which aren’t currently available in Hugo’s template functions.
So before I go making a pull request for something specific that I need to make this work, I thought I would ask
Is there a better way of building a tag list with weights?
Should I implement some function to take .Site.Taxonomies.tags (which returns a map of name to an array of items) and a variable number of steps to return mapping of name to weight or is there something more generic I can build?
I know this is an old topic, but I ended up here myself by searching. I see that waddles is trying to avoid inline styles, but if you don’t mind that, you might find this useful. At least it works for me:
{{ if not (eq (len $.Site.Taxonomies.tags) 0) }}
{{ $fontUnit := "rem" }}
{{ $largestFontSize := 2.0 }}
{{ $smallestFontSize := 1.0 }}
{{ $fontSpread := sub $largestFontSize $smallestFontSize }}
<!--<div>Font size unit: {{ $fontUnit }}</div>
<div>Font min size: {{ $smallestFontSize }}</div>
<div>Font max size: {{ $largestFontSize }}</div>
<div>Font size spread: {{ $fontSpread }}</div>-->
{{ $max := len (index $.Site.Taxonomies.tags.ByCount 0).Pages }}
<!--<div>Max tag count: {{ $max }}</div>-->
{{ $min := len (index $.Site.Taxonomies.tags.ByCount.Reverse 0).Pages }}
<!--<div>Min tag count: {{ $min }}</div>-->
{{ $spread := sub $max $min }}
<!--<div>Tag count spread: {{ $spread }}</div>-->
{{ $fontStep := div $fontSpread $spread }}
<!--<div>Font step: {{ $fontStep }}</div>-->
<ol id="tag-cloud">
{{ range $name, $taxonomy := $.Site.Taxonomies.tags }}
{{ $currentTagCount := len $taxonomy.Pages }}
{{ $currentFontSize := (add $smallestFontSize (mul (sub $currentTagCount $min) $fontStep) ) }}
<!--Current font size: {{$currentFontSize}}-->
<li><a href="{{ "/tags/" | relLangURL }}{{ $name | urlize }}" style="font-size:{{$currentFontSize}}{{$fontUnit}}">{{ $name }} ({{$currentTagCount}})</a></li>
{{ end }}
</ol>
{{ end }}
Thanks for improving my version. I just tried my code on my own content and I’m a newbie at Hugo.
Would you mind explaining what the “corner cases that can cause Hugo to crash” are? I see the possible division by 0 when all posts have the same number of tags. Anything else?
For me your code crashes at line 1 with <len .Data.Terms>: error calling len: len of untyped nil.
In which template did you put your code? Not all the templates has access to .Data.Terms. This partial was supposed to be used on layouts/_default/terms.html. So, the site’s /tags/ or /categories/ url would show the cloud.
Yeah, division by 0 is one such case. Also, in multi-language sites, if there is no posts available under a certain language, that’s another case (though it’s very unlikely to face it, but one of my theme’s users reported it).
I see now that you wrote _"This partial is written to be used on layouts/defaults/terms.html template" when you posted the code as well. I wrote mine to be a partial I can include on any page. I haven’t seen a tag cloud as a separate page before, but I guess that is a use case as well.
Thanks for the info about the multi-language problem. My blog (which I’m build with Hugo) is English only, but as a non-native English speaker I certainly appreciate the effort to support that