Search code examples
gogo-templates

Last item in a template range


Given the template:

{{range $i, $e := .SomeField}}
        {{if $i}}, {{end}}
        $e.TheString
{{end}}

This can output:

one, two, three

If, however, I want to output:

one, two, and three

I'd need to know which is the last element in the range above.

I can set a variable that holds the length of the array .SomeField, but that will always be 3, and the $i value above will only ever get to 2. And you can't perform arithmetic in templates from what I've seen.

Is detecting the last value in a template range possible? Cheers.


Solution

  • This is probably not the most elegant solution but it's the best I could find:

    http://play.golang.org/p/MT91mLqk1s

    package main
    
    import (
        "os"
        "reflect"
        "text/template"
    )
    
    var fns = template.FuncMap{
        "last": func(x int, a interface{}) bool {
            return x == reflect.ValueOf(a).Len() - 1
        },
    }
    
    
    func main() {
        t := template.Must(template.New("abc").Funcs(fns).Parse(`{{range  $i, $e := .}}{{if $i}}, {{end}}{{if last $i $}}and {{end}}{{$e}}{{end}}.`))
        a := []string{"one", "two", "three"}
        t.Execute(os.Stdout, a)
    }
    

    Note: You can also do it without reflect using the len function (credit to Russ Cox): http://play.golang.org/p/V94BPN0uKD

    c.f.