When working with complex data structures involving multiple nested types, passing multiple values from one template to another becomes a challenge. Let's explore a scenario where we have these structs:
In our main function, we attempt to execute a template with CityWithSomeData, which is an array of City structures:
tpl.ExecuteTemplate(resWriter, "cities.gohtml", CityWithSomeData)
Passing Multiple Values in Templates
Unfortunately, it's not possible to pass multiple values directly in templates using the {{.}} syntax. According to the text/template documentation, the syntax for {{template}} action allows for only one optional data value to be passed.
{{template "name"}} The template with the specified name is executed with nil data. {{template "name" pipeline}} The template with the specified name is executed with dot set to the value of the pipeline.
Wrapping Data in a Single Value
To overcome this limitation, we need to wrap our multiple data values into a single value that can be passed as input to the template. However, since we can't write Go code in templates, we'll create a custom wrapper function:
func Wrap(shops []Destination, cityName, regionName string) map[string]interface{} { return map[string]interface{}{ "Shops": shops, "CityName": cityName, "RegionName": regionName, } }
This Wrap() function takes an array of Destination values, along with city and region names, and returns a map that combines all these data. Now, we can use this function in our template:
const src = ` {{define "data"}} City: {{.CityName}}, Region: {{.RegionName}}, Shops: {{.Shops}} {{end}} {{- range . -}} {{$city:=.Name}} {{- range .Regions -}} {{$region:=.Name}} {{- template "data" (Wrap .Shops $city $region) -}} {{end}} {{- end}}`
Updated Example
Here's an updated example that demonstrates how the wrapper function is used:
t := template.Must(template.New("cities.gohtml").Funcs(template.FuncMap{ "Wrap": Wrap, }).Parse(src)) CityWithSomeData := []City{ { Name: "CityA", Regions: []Region{ {Name: "CA-RA", Shops: []Destination{{"CA-RA-SA"}, {"CA-RA-SB"}}}, {Name: "CA-RB", Shops: []Destination{{"CA-RB-SA"}, {"CA-RB-SB"}}}, }, }, { Name: "CityB", Regions: []Region{ {Name: "CB-RA", Shops: []Destination{{"CB-RA-SA"}, {"CB-RA-SB"}}}, {Name: "CB-RB", Shops: []Destination{{"CB-RB-SA"}, {"CB-RB-SB"}}}, }, }, } if err := t.ExecuteTemplate(os.Stdout, "cities.gohtml", CityWithSomeData); err != nil { panic(err) }
Output
City: CityA, Region: CA-RA, Shops: [{CA-RA-SA} {CA-RA-SB}] City: CityA, Region: CA-RB, Shops: [{CA-RB-SA} {CA-RB-SB}] City: CityB, Region: CB-RA, Shops: [{CB-RA-SA} {CB-RA-SB}] City: CityB, Region: CB-RB, Shops: [{CB-RB-SA} {CB-RB-SB}]
By wrapping multiple data values into a single map using the Wrap() function, we successfully passed them between templates in our Go application.
The above is the detailed content of How Can I Pass Multiple Values Between Go Templates?. For more information, please follow other related articles on the PHP Chinese website!