Trying to understand scope in shortcode

Hey everyone,

I just spent a chunk of time trying to get a shortcode to do what I wanted and I think I’m just missing something.

Let’s say I have a short code that takes a named argument Arg.

{{< my-shortcode arg="testing" >}}

Inside that shortcode I have the following, which works:

{{ define "inner-template" }}
  <p>examplevar: {{$.examplevar}}</p>
  <p>arrayitem: {{$.arrayitem}}</p>
{{end}}

{{ range .Site.Data.exampleData }}
    {{ $dict := (dict "examplevar" $.Params.Arg "arrayitem" .) }}
    {{ template "inner-template" $dict }}
{{ end }}

My first version of this, was:

{{ define "inner-template" }}
  <p>examplevar: {{$.examplevar}}</p>
  <p>arrayitem: {{$.arrayitem}}</p>
{{end}}

{{ range .Site.Data.exampleData }}
    {{ template "inner-template" (dict "examplevar" $.Params.Arg "arrayitem" .) }}
{{ end }}

The problem here is that examplevar isn’t set in the inner-template block.

I don’t understand how the position of dict can affect the value of examplevar.

Can anyone explain what’s happening?

Try $.Params.arg.

The name Arg works, but passing it into “inner-template” doesn’t work if the dict is defined inline.

Testing it works for me with that one change. Do you have a repo somewhere we can have a look at to reproduce your issue? What Hugo version are you using?

Notice how @pointyfar used .arg not .Arg

Apologies, I naively thought that it wouldn’t make a difference but it completely fixes the issue.

Do you know why this makes a difference? Is it best practice to use the exact names for variables instead of the uppercase (What I assumed was “public”) variable name?

Thanks for the answer

@gauntface It is explained here:

Page-level .Params are only accessible in lowercase.