Home >Backend Development >Golang >How Can I Pass Multiple Values Between Go Templates?

How Can I Pass Multiple Values Between Go Templates?

Patricia Arquette
Patricia ArquetteOriginal
2024-12-04 14:28:12304browse

How Can I Pass Multiple Values Between Go Templates?

Passing Multiple Values Between Templates

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:

  • City struct: Contains properties like ID, name, and a slice of Region structures.
  • Region struct: Contains ID, name, and various other slices representing different data types.

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn