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


#1

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”, …


#2

You can do something ala:

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

#3

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

https://ox-hugo.scripter.co/test/posts/blackfriday-ext-enabling-disabling-toml#debug


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


How to check if a variable is String or Array
Way to view check value of site variables
#4

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


#5

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.


#6

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.


#7

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?


#8

Start with PR:

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


#9

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.


#10

Created a new issue to track this: