0

I'm pretty inexperienced with go templates and I've got a situation where I have a top level template, into which I want to dynamically inject inner templates, in which there should be some injected value. The solution I have works, it looks ugly or naive to me. The code below is contrived, but represents accurately what I've come up with.

First, the inner template is executed, setting the "Value" to produce a String, which is then injected into the wrapping template "top".

Is there a way to combine these steps into a single invocation, such that the inner template is evaluated with the value, and the injected into the outer template?

package main

import (
    "bytes"
    "fmt"
    "text/template"
)

// top should dynamically wrap an inner template.
const top = `Top, inner: {{.Inner}}
`
const inner1 = `Inner1: {{.Value}}
`
const inner2 = `Inner2: {{.Value}}
`

var innerds = []string{"inner1", "inner2"}

var t = new(template.Template)


// hardcoded for simplicity, dynamic IRL
var val = struct {
    Value string
}{"foobar!"}

func main() {
    template.Must(t.New("top").Parse(top))
    template.Must(t.New("inner1").Parse(inner1))
    template.Must(t.New("inner2").Parse(inner2))

    for _, innerTmpName := range innerds {
        
        innerBuf := new(bytes.Buffer)
        _ = t.ExecuteTemplate(innerBuf, innerTmpName, val) // innerBuf == "Inner1: foobar!"

        fmt.Println(innerBuf.String())

        topBuf := new(bytes.Buffer)
        _ = t.ExecuteTemplate(topBuf, "top", struct{Inner string}{innerBuf.String()}) // topBuf == "Top, inner: Inner1: foobar!"
                 
        fmt.Println(topBuf.String())
    }
}

Output:

Top, inner: Inner1: foobar!

Top, inner: Inner2: foobar!

jcope
  • 131
  • 1
  • 7
  • like this https://play.golang.org/p/MHQ8KTkNU2y ? –  Dec 10 '20 at 20:31
  • 2
    Templates may be associated, and if they are, they can refer to each other, they can be embedded in other templates. For details, see [Go template name](https://stackoverflow.com/questions/41176355/go-template-name/41187671#41187671). Then see this question how templates can be included in another one: [How to use a field of struct or variable value as template name?](https://stackoverflow.com/questions/28830543/how-to-use-a-field-of-struct-or-variable-value-as-template-name/28831138#28831138) – icza Dec 10 '20 at 20:35
  • Thank you both - it seems that I've stumbled onto [Alternative#1](https://stackoverflow.com/questions/28830543/how-to-use-a-field-of-struct-or-variable-value-as-template-name/28831138#28831138) of @icza 's 2nd link. I guess that makes this a duplicate. Per the Rob Pike quote, it sounds like what I'm looking for isn't actually idiomatic, and what I've got is decent enough pattern. Edit - I see icza actually authored that answer too - so thanks for that excellent write up! – jcope Dec 10 '20 at 21:14

0 Answers0