If your input gets bigger (more complex) or if you need to substitute different values multiple times, then templates are more effective, cleaner and more flexible. Check out the text/template package.
The template package parses your template once, builts a tree from it, and once you need to replace values, it builds the output on the fly.
Take a look at this example:
const templ = `Hi {{.Name}}!
Welcome {{.Place}}.
Please bring {{.ToBring}}
`
You can parse such a template with this line:
t := template.Must(template.New("").Parse(templ))
Prepare its input data either as a struct or as a map:
data := map[string]string{
"Name": "Bob",
"Place": "Home",
"ToBring": "some beers",
}
And you can have the result with Template.Execute():
err := t.Execute(os.Stdout, data) // Prints result to the standard output
Here's the complete, runnable example: (try it on the Go Playground)
package main
import (
"os"
"text/template"
)
func main() {
data := map[string]string{
"Name": "Bob",
"Place": "Home",
"ToBring": "some beers",
}
t := template.Must(template.New("").Parse(templ))
if err := t.Execute(os.Stdout, data); err != nil { // Prints result to the standard output
panic(err)
}
// Now change something:
data["Name"] = "Alice"
data["ToBring"] = "a Teddy Bear"
if err := t.Execute(os.Stdout, data); err != nil {
panic(err)
}
}
const templ = `
Hi {{.Name}}!
Welcome {{.Place}}.
Please bring {{.ToBring}}
`
Output:
Hi Bob!
Welcome Home.
Please bring some beers
Hi Alice!
Welcome Home.
Please bring a Teddy Bear
Getting the result as a string:
If you want the result as a string, you can write the result to a bytes.Buffer and get the string using the Buffer.String() method:
buf := bytes.Buffer{}
t.Execute(&buf, data)
var result string = buf.String()
Complete program (try it on the Go Playground):
package main
import (
"bytes"
"fmt"
"text/template"
)
func main() {
data := map[string]string{
"Name": "Bob",
"Place": "Home",
"ToBring": "some beers",
}
fmt.Print(Execute(data))
}
var t = template.Must(template.New("").Parse(templ))
func Execute(data interface{}) string {
buf := bytes.Buffer{}
if err := t.Execute(&buf, data); err != nil {
fmt.Println("Error:", err)
}
return buf.String()
}
const templ = `
Hi {{.Name}}!
Welcome {{.Place}}.
Please bring {{.ToBring}}
`
fmt.Sprintfis the best way to go if you don't have any complex template processing to do.