Can one use array for isset? And why `if` vs. `isset`

I’ve worked around the problem but I am now curious, is there anyway to use a map in isset to determine if some value in that map is set? For example:

image:
 - source: test.png
   alt: null

If I try {{ isset .Params.image "alt" }} it errors out, or using any other combination I can think of.

One work around is to not make it a map, i’m not sure what this structure would be called:

image:
  source: test.png
  alt: null

Then the function above would work. But sometimes you have to use a map so i’m curious if there is a way to do it.

Looking at the corresponding JSON for your YAML snippets may shed some light.

Your first snippet is actually an array:

{
   "image": [
      {
         "source": "test.png",
         "alt": null
      }
   ]
}

Your second snippet is an object (or map as you say):

{
   "image": {
      "source": "test.png",
      "alt": null
   }
}

I don’t know the proper names for these structures, will I guess now I do. So isset can’t work with an array basically because there are having no keys below the main one, without entering the array which I don’t think you can do.

Why would one use isset when it seems to operate and output the same as if ? And if throws a fewer warnings or errors and has fewer formatting requirements. An empty key returns false, a non-existent key returns false.

To specifically check that a param has been set to a falsy value.

Here we call the same shortcode three times. Note that the param is unquoted (boolean).

{{< foo >}}
{{< foo x=true >}}
{{< foo x=false >}}

If we want to set the default value to true:

{{/* Set default */}}
{{ $x := true }}

{{/* Get param */}}
{{ if .Params }}
  {{ if isset .Params "x" }}
    {{ $x = .Get "x" }}
  {{ end }}
{{ end }}

{{/* Display param */}}
{{ $x }}
2 Likes

Wouldn’t this do the same thing?

{{ if .Params.x }}
    {{ $x = .Get "x" }}
{{ end }}

Or maybe it would in a template but not a shortcode where the arguments aren’t mapped like that?

1 Like

No. Try it.

You are of course correct with respect to shortcodes. And I did try it. The params of a shortcode cannot be access with object dot notation. They have to be accessed with .Get "param". So what your shortcode is doing is checking if there are any Params, and then checking if the “x” param is set, and then getting it if so.

For layout templates, I did the below. And it seems if you want something that is falsy to return false, you should use if. And I don’t know how useful isset would be in such a situation. Especially since it returns true if the key exists at all, whether it has an empty value, null, or something.

If I add post1.md as:

---
title: Test1

test1: true
test2: false
test3: null

---

And single.html as:

{{ .Content }}

{{ if .Params.test1 }}
{{ printf "if test1 %s" .Params.test1 }}
{{ end }}
<p></p>
{{ if isset .Params "test1" }}
  {{printf "if isset test1 %s"  .Params.test1 }}
{{ end }}
<p></p>
{{ if .Params.test2 }}
{{ printf "if test2 %s" .Params.test2 }}
{{ end }}
<p></p>
{{ if isset .Params "test2" }}
  {{ printf "if isset test2 %s"  .Params.test2 }}
{{ end }}
<p></p>
{{ if .Params.test3 }}
{{ printf "if test3 %s" .Params.test3 }}
{{ end }}
<p></p>
{{ if isset .Params "test3" }}
  {{ printf "if isset test3 %s"  .Params.test3 }}
{{ end }}

Then the result is:

if test1 %!s(bool=true)
if isset test1 %!s(bool=true)
if isset test2 %!s(bool=false)
if isset test3 %!s(<nil>)
1 Like

I haven’t read this entire thread, but isset was added, I suspect, when if and with had some issues that is now fixed. I cannot remember the last time I used isset.

2 Likes

I use isset to check if a key exist regardless of its value. if and with will return false if the key is set but falsy. isset will only return false if the key is absent… Hope I’m not wrong :slight_smile:

4 Likes

That is incorrect. A shortcode parameter “x” can be accessed with any of the following:

{{ .Get "x" }}
{{ .Params.x }}
{{ index .Params "x" }}
2 Likes

Works.

Gives the error shortcodes\foo.html:13:10": execute of template failed at <.Params.x>: can’t evaluate field x in type interface {}

Gives the error shortcodes\foo.html:14:3": execute of template failed at <index .Params "x">: error calling index: cannot index slice/array with type string

What am I missing?

shortcode is:

{{/* Set default */}}
{{ $x := true }}

{{/* Get param */}}
{{ if .Params }}
  {{ if isset .Params "x" }}
    {{ $x = .Get "x" }}
  {{ end }}
{{ end }}

{{/* Display param */}}
{{ .Get "x" }}
{{ .Params.x }}
{{ index .Params "x" }}
{{ $x }}

Which is called in content file as you described above.

@jmooring I’m still not able to get what you described working from a short code. Only the Get works.

EDIT: I’m sorry, I realized just now testing it again why it wasn’t working. I had called the shortcode in one instance without the x= arg set, so those two methods would error out since it assumes it exists. Where get won’t error if it doesn’t exist.

Thank you for the lesson!

2 Likes