I’m using Hugo v0.29. I do conditional variable assignments in my shortcodes based on whether an optional shortcode parameter was provided. I have found that Hugo doesn’t behave consistently for first ($0) and second ($1) shortcode parameter evaluations.
The following code, using the cond
function, produces the correct output and no runtime errors when the shortcode is called with or without parameters (i.e., w/wo Param $0):
{{ $var := (cond (isset $.Params 0) (.Get 0) "No Param $0") }}
$var = "{{- $var -}}"
However, the same code but applied to the second parameter ($1) produces a “No shortcode param at .Get 1 in page …, have params:” runtime error when the shortcode is called with only one parameter (i.e., without Param $1), even though the output is rendered correctly:
{{ $var := (cond (isset $.Params 1) (.Get 1) "No Param $1") }}
$var = "{{- $var -}}"
==>
(a) The behavior is different when evaluating the first ($0) and second ($1) parameter, which is confusing.
(b) For the second-parameter ($1) code, the error is produced for the .Get 1
call in the true
clause of the cond
function, even though this clause is not executed when the shortcode is called without a second parameter (because the isset $.Params 1
condition correctly evaluates to false
). --> It seems that Hugo validates the true
clause even when the condition evaluates to false
, which defeats the purpose of the conditional logic.
Again, the same code for the first-parameter ($0) doesn’t produce an error, and in both cases the output is good both when the shortcode is called with and without the relevant parameter.
My current solution is to use Scratch
for parameter $1 evaluations, but I feel this unnecessarily complicates the code:
{{ $.Scratch.Set "var" "default value" }}
{{ if (isset $.Params 1) }}{{ $.Scratch.Set "var" (.Get 1) }}{{ end }}
var = {{ $.Scratch.Get "var" }}
Is there a simpler way to do a conditional variable assignment based on whether parameter $1 was passed to the shortcode?
I also noticed other related differences for parameter $0 and $1 evaluations. For example, when the following shortcode is called without a first parameter ($0), there’s no runtime error, the if $var
condition evaluates to false
, and the else
clause is executed:
{{ $var := .Get 0 }}
{{ if $var }}$var = {{- $var -}}{{ else }}$var is not set{{end }}
However, if you change .Get 0
to .Get 1
and call the shortcode without a second parameter ($1), (a) The .Get 1
call in the variable assignment produces a runtime error; (b) The condition evaluates to true
, which produces “error: index out of range for positional param at position 1” in the output for the $var
reference in the if
clause.
I can understand why this code might not be valid, but then it shouldn’t work for the first parameter ($0) either?!