How to test if a variable is of a certain type?

Hello,

Is there a way I can test if a variable is a single value or a list or a map or a …?

I am missing test functions like “IsList”, “IsMap”, …

You can do something ala:

{{ if eq (printf "%T" true) "bool" }}
7 Likes

Thanks!

It ended up being a bit ugly though, but it worked.

Partial + CSS

Usage

  1. Save the CSS in above gist to your site.
  2. Add the debugprint.html as a partial.
  3. Use that partial in your templates as:
    {{ partial "debugprint.html" .Params }}
    

Example


PS: I just realized that that partial can be called recursively! Still looking forward to comments on how I can optimize it further.

That doesn’t look very pretty … If you want to put together a PR with reflect.IsMap and reflect.IsSlice

1 Like

Next, I started updating that debugprint.html partial to just print potential useful vars from .Site. And now I am needing to do:

{{ $typeIsArray          := (findRE "^([[][]]|.*TaxonomyList)" $type 1 | len | eq 1) }} <!-- match ^[] -->
{{ $typeIsMap            := (findRE "^(map[[].+[]]|.*SiteSocial)" $type 1 | len | eq 1) }} <!-- match ^map[*] -->

Is there a generic way to tell if something is a map or an array (slice?). I simply need to know if I need to use {{ range $value }} or {{ range $key1, $value1 := $value }} or none of those… I don’t care of the exact map/slice type.

Also, is there a better way to write:

                    {{ if $type1IsTime }}
                        <!-- Print the date only if it is not at its initial value of Jan 1, 0001 -->
                        {{ if (ne "0001-01-01" ($value1.Format "2006-01-02")) }}
                            {{ printf "<tr><td class=\"key\">%s</td><td class=\"type\">%s</td><td class=\"value\">" $key1 $type1 | safeHTML }}
                            {{ partial "debugprint.html" $value1 }} <!-- Recursive call FTW! -->
                            {{ printf "</td></tr>" | safeHTML }}
                        {{ end }}
                    {{ else }}
                        {{ printf "<tr><td class=\"key\">%s</td><td class=\"type\">%s</td><td class=\"value\">" $key1 $type1 | safeHTML }}
                        {{ partial "debugprint.html" $value1 }} <!-- Recursive call FTW! -->
                        {{ printf "</td></tr>" | safeHTML }}
                    {{ end }}

I basically want to do something like (PSEUDO-code below):

                    {{ if (or (not $type1IsTime)
                              (and $type1IsTime
                                   (ne "0001-01-01" ($value1.Format "2006-01-02")))) }}
                        <!-- Print the date only if it is not at its initial value of Jan 1, 0001 -->
                        {{ printf "<tr><td class=\"key\">%s</td><td class=\"type\">%s</td><td class=\"value\">" $key1 $type1 | safeHTML }}
                        {{ partial "debugprint.html" $value1 }} <!-- Recursive call FTW! -->
                        {{ printf "</td></tr>" | safeHTML }}
                    {{ end }}

But cannot figure out how to write that whole OR condition in Go templates.

I just had a look at https://github.com/gohugoio/hugo/blob/master/tpl/collections/reflect_helpers.go.

I don’t think I am ready to submit to a PR to Go code as I need to figure out first of all what ‘reflect’ is, and what to put in the case statements (base on examples of isUint, etc. Also I have never coded in it Go, so I need to put in considerable time to learn Go debugging, etc.

Can you please add those functions?

Start with PR:

https://github.com/gohugoio/hugo/pull/2427

So the PR is already there. Can that please be merged?

TIL there’s something called Kind that’s a broader categorization of Type, and the kindIs function in that PR is exactly what I need, assuming that function can be used in templates/partials.

Created a new issue to track this:

2 Likes

Thanks a lot… Helped me resolve my issue with separating array from string.

Hi I have another solution. Check if the index 0 of an array isset. And if not it cant be an array:
Thats from a JSON source where sometimes .description is an array and sometimes it ist not.

{{ if (isset .description 0)  }}  
 {{ range .description }}
 {{ . }}  
 {{ end }}
{{ else }}
{{ .description }}
{{ end }}

But it leads to this error message:

WARNING: calling IsSet with unsupported type “string” (string) will always return false.