Replacing existing JS array with a static template

Hi,

I have this page https://raspi.github.io/projects/uptime/ calculating SLA % uptimes in JS and I’m currently changing into Hugo.

I’ve created this shortcode:

{{ $seconds_per_year := 31536000 }}
{{ $percents := (seq 99) }}

<table>
{{ range $i, $p := $percents }}

{{ $secs := sub 100 $p }}
{{ $secs := div $secs 100 }}
{{ $secs := mul $secs $seconds_per_year }}
<tr>
	<td>{{ $p }} %</td>
	<td>{{ $secs_in_human }} TODO</td>
	<td>{{ $secs }}</td>
</tr>

{{ end }}
</table>

My problems are:

  • $secs is always 0
  • How I add 0.1 … 0.5 to $percents
  • How I add 99.9 … 99.99999 to $percents
  • How to do the “x seconds, x minutes, …” (as other shortcode?)

Floating values are returned if you do your math with a decimal.

See this post and this one for examples.

Ok, now it’s:

{{ $seconds_per_year := 31536000.0 }}
{{ $percents := (seq 99.0) }}

<table>
{{ range $i, $p := $percents }}

{{ $secs := sub 100.0 $p }}
{{ $secs := div $secs 100.0 }}
{{ $secs := mul $secs $seconds_per_year }}
<tr>
	<td>{{ $p }} %</td>
	<td>{{ $secs | lang.NumFmt "." "," "-" 2 }}</td>
</tr>

{{ end }}
</table>

Error:
shortcodes/slauptime.html:12:20: executing “shortcodes/slauptime.html” at <lang.NumFmt>: error calling NumFmt: unable to cast “.” of type string to int

I tried:

<td>{{ lang.float64 $secs | lang.NumFmt "." "," "-" 2 }}</td>

and:

<td>{{ lang.NumFmt "." "," "-" 2 lang.float64 $secs }}</td>

Yikes! The docs are wrong. We’ll get that fixed, but here’s what you need:

lang.NumFmt PRECISION NUMBER [OPTIONS]

NumFmt formats a number with the given precision using the negative, decimal, and grouping options. The options parameter is a string consisting of “<negative> <decimal> <grouping>”. The default options value is “- . ,”.

Note that numbers are rounded up at 5 or greater. So, with precision set to 0, 1.5 becomes 2, and 1.4 becomes 1.

In your case, the following should work:

{{ lang.NumFmt 2 $secs }}

Ok,

Now I’m stuck with how to convert those seconds to relative time.

{{ $num_fmt := "- , &nbsp;"}}
{{ $total_seconds := int (.Get "secs") }}
{{ $percents := slice 99.99999 99.9999 99.999 99.99 99.9 99.0 98.0 97.0 96.0 95.0 94.0 93.0 92.0 91.0 90.0 89.0 88.0 87.0 86.0 85.0 84.0 83.0 82.0 81.0 80.0 79.0 78.0 77.0 76.0 75.0 74.0 73.0 72.0 71.0 70.0 69.0 68.0 67.0 66.0 65.0 64.0 63.0 62.0 61.0 60.0 59.0 58.0 57.0 56.0 55.0 54.0 53.0 52.0 51.0 50.0 49.0 48.0 47.0 46.0 45.0 44.0 43.0 42.0 41.0 40.0 39.0 38.0 37.0 36.0 35.0 34.0 33.0 32.0 31.0 30.0 29.0 28.0 27.0 26.0 25.0 24.0 23.0 22.0 21.0 20.0 19.0 18.0 17.0 16.0 15.0 14.0 13.0 12.0 11.0 10.0 9.0 8.0 7.0 6.0 5.0 4.0 3.0 2.0 1.0 0.5 0.1 }}

<p>Using {{ lang.NumFmt 0 $total_seconds $num_fmt | htmlUnescape }} seconds as average.</p>

<table>
{{ range $p := $percents }}

{{ $secs := sub 100.0 $p }}
{{ $secs := div $secs 100.0 }}
{{ $secs := mul $secs $total_seconds }}
<tr>
	<td>{{ $p }}&nbsp;%</td>
	<td>
	{{ $dur := time (int $secs) }}
	{{ printf "%T" $dur }}
	</td>
	<td>{{ lang.NumFmt 2 $secs $num_fmt | htmlUnescape}} seconds</td>
</tr>

{{ end }}
</table>

I’m getting $dur as time.Time and I think time.Duration is the correct one according to docs, but I can’t quite figure out how to. And can I somehow add days and weeks to duration struct?

Also $percents is so long string because of a bug.

I don’t believe you can create a time.Duration value today. Created an issue to track this enhancement request.

https://github.com/gohugoio/hugo/issues/3828

Ok,

Here’s the working end result. But relative times are a bit off here and there (needs floats).

{{ $num_fmt := "- , &nbsp;"}}
{{ $total_seconds := int (.Get "secs") }}
{{ $percents := slice 99.99999 99.9999 99.999 99.99 99.9 99.5 99.0 98.0 97.0 96.0 95.0 94.0 93.0 92.0 91.0 90.0 89.0 88.0 87.0 86.0 85.0 84.0 83.0 82.0 81.0 80.0 79.0 78.0 77.0 76.0 75.0 74.0 73.0 72.0 71.0 70.0 69.0 68.0 67.0 66.0 65.0 64.0 63.0 62.0 61.0 60.0 59.0 58.0 57.0 56.0 55.0 54.0 53.0 52.0 51.0 50.0 49.0 48.0 47.0 46.0 45.0 44.0 43.0 42.0 41.0 40.0 39.0 38.0 37.0 36.0 35.0 34.0 33.0 32.0 31.0 30.0 29.0 28.0 27.0 26.0 25.0 24.0 23.0 22.0 21.0 20.0 19.0 18.0 17.0 16.0 15.0 14.0 13.0 12.0 11.0 10.0 9.0 8.0 7.0 6.0 5.0 4.0 3.0 2.0 1.0 0.5 0.1 0.01}}
{{ $single := slice "week" "day" "hour" "minute" "second" }}
{{ $plural := slice "weeks" "days" "hours" "minutes" "seconds" }}

<p>Using <strong>{{ lang.NumFmt 0 $total_seconds $num_fmt | htmlUnescape }}</strong> seconds as average.</p>

<table>
<tr>
	<td>SLA percentage</td>
	<td>Relative time</td>
	<td>Seconds</td>
</tr>
{{- range $p := $percents }}
{{- $secs := sub 100.0 $p }}
{{- $secs := div $secs 100.0 }}
{{- $secs := mul $secs $total_seconds }}
{{- $secs_f := lang.NumFmt 2 $secs $num_fmt | htmlUnescape }}
{{- $s := int $secs }}
{{- $weeks := div $s 604800 }}
{{- $s := mod $s 604800 }}
{{- $days := div $s 86400 }}
{{- $s := mod $s 86400 }}
{{- $hours := div $s 3600 }}
{{- $s := mod $s 3600 }}
{{- $minutes := div $s 60 }}
{{- $s := mod $s 60 }}
{{- $result := slice $weeks $days $hours $minutes $s }}
<tr>
	<td>{{- $p -}}&nbsp;%</td>
	<td>
	{{- range $idx, $res := $result -}}
		{{- if gt $res 0 }}
			{{ $res }}
			{{ if eq 1 $res }}{{ index $single $idx }}{{ else }}{{ index $plural $idx }}{{ end }}
			{{- if gt (index $result (add $idx 1)) 0 }}, {{ end }}
		{{- end -}}
	{{- end -}}
	</td>
	<td>{{- $secs_f -}}</td>
</tr>
{{- end -}}
</table>
1 Like

The recent v0.27 Hugo release includes a new duration function.

1 Like