Shortcode with if/else logic losing its variable

Hi

I have shortcode with a basic if/else condtional logic … and a range… but i’m getting error is … undefined variable - I don’t know why my variable is being lost

This will return related content (by tag or category)

shortcode example

{{< related taxo=tags count=3 term=hugo >}}

{{ $taxo := .Get "taxo"}}
{{ $count := .Get "count"}}
{{ $term := .Get "term"}}
  {{ if eq $taxo "tags" }} 
    {{ $ds_related = where (index .Site.Taxonomies.tags (lower $term)).Pages "Type" "in" site.Params.mainSections }}
  {{ else if eq $taxo "categories"}}
    {{ $ds_related = where (index .Site.Taxonomies.categories (lower $term)).Pages "Type" "in" site.Params.mainSections }}
  {{ else }}
    Warning - invalid taxo
    {{ end }}

  <h2>What have I said about {{ humanize ($term) }}?</h2>
  <ul class="list">
    {{ range first $count $ds_related }}
        <li class="list"><a href="{{ .Page.RelPermalink }}">{{ .Page.Title }}</a></li>
    {{ end }}
  </ul>

I also tried {{ with $ds_related }} but same error

I don’t know why its losing my variable :frowning:

A variable must be defined (with :=) before it can be assigned a value. You are attempting to assign a value to $ds_related (with =) without first defining it.

Hi @jmooring … well spotted … thanks

It’s still giving me the same error.

I even made the code a bit shorter - and its still errors on line 9 - undefined variable (where I’m doing {{ range $count $ds_related }}

Its definitely the IF / ELSE logic. or the `{{end}} - cause this shortcode works

{{< related count=3 term=hugo >}}

{{ $count := .Get "count"}}
{{ $term := .Get "term"}}
    {{ $ds_related := where (index .Site.Taxonomies.tags (lower $term)).Pages "Type" "in" site.Params.mainSections }}
  <h2>What have I said about {{ humanize ($term) }}?</h2>
  <ul class="list">
    {{ range first $count $ds_related }}
        <li class="list"><a href="{{ .Page.RelPermalink }}">{{ .Page.Title }}</a></li>
    {{ end }}
  </ul>

Your shortcode works fine for me. No errors.

Hi @jmooring thanks for the help

… do you mean

  1. the shortcode with the if / else logic and just correcting the :=
    or
  2. the second code example that doesnt have if / else – cause yes – that worked for me

If you have it working with if / else logic - can you send me the gist / file please so i can compare

thanks

Please post code that is not working, and post the complete text of the error message.

HI …

shortcode example {{< related taxo=tags count=3 term=hugo >}}

file is called related.html code is …

{{ $taxo := .Get "taxo"}}
{{ $count := .Get "count"}}
{{ $term := .Get "term"}}
{{ if .IsNamedParams }}
  {{ if eq $taxo "tags" }} 
    {{ $ds_related := where (index .Site.Taxonomies.tags (lower $term)).Pages "Type" "in" site.Params.mainSections }}
  {{ else if eq $taxo "categories"}}
    {{ $ds_related := where (index .Site.Taxonomies.categories (lower $term)).Pages "Type" "in" site.Params.mainSections }}
  {{ else }}
    Warning - invalid taxo
    {{ end }}
  <h2>What have I said about {{ humanize ($term) }}?</h2>
  <ul class="list">
    {{ range first $count $ds_related }}
        <li class="list"><a href="{{ .Page.RelPermalink }}">{{ .Page.Title }}</a></li>
    {{ end }}
  </ul>
{{ else }}
Warning - check your tags or count
{{ errorf "missing value for param 'name': %s" .Position }}
{{ end }}

error is …

Error: add site dependencies: load resources: loading templates: “/Users/damien/dev/hugo-dev/themes/shortcode/layouts/shortcodes/related.html:14:1”: parse failed: template: shortcodes/related.html:14: undefined variable “$ds_related”

Variables defined within if, with, and range blocks are not visible outside of the block in which they are defined. You need to define the variable at the top, where you have defined $taxo, $count, and $term.

1 Like

ok … I tried that … now I’m getting a 'range can’t iterate over` error - and I’ve also tried using $

What I really wanted to do — was to append / splice the range query … and that way avoid the if / else

so you can swap categories for tags in the below

{{ $related := where (index $.Site.Taxonomies.categories (lower $term)).Pages "Type" "in" site.Params.mainSections }}

gist is here … if you want it

Solved it … using .Scratch to carry my range / variable

Your code didn’t work because you initialized the variable above the if-else block, then you initialized it again (twice) within the if-else block. Use := to initialize, and use = to assign value to a previously initialized variable . Syntax and scope…

{{- $var := 1 -}}
var at line 2 = {{ $var }} <br>

{{- if true -}}
  var at line 5 = {{ $var }} <br>
  {{- $var := 2 -}}
  var at line 7 = {{ $var }} <br>
{{- end -}}

var at line 10 = {{ $var }} <br>

produces:

var at line 2 = 1
var at line 5 = 1
var at line 7 = 2
var at line 10 = 1

A variable’s scope extends to the “end” action of the control structure (“if”, “with”, or “range”) in which it is declared, or to the end of the template if there is no such control structure. A template invocation does not inherit variables from the point of its invocation.

Additionally, you can replace your if-else block with:

{{ $ds_related := where (index .Site.Taxonomies $taxo (lower $term)).Pages "Type" "in" site.Params.mainSections }}

See https://golang.org/pkg/text/template/#hdr-Functions.

index

Returns the result of indexing its first argument by the following arguments. Thus “index x 1 2 3” is, in Go syntax, x[1][2][3]. Each indexed item must be a map, slice, or array.

1 Like

Damn I swear i tried that approach - cause that is minimal code, which i love :heart_decoration:

Thanks

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.