Range Loop Variable Scope in Go Templates
In Go templating, it's important to understand how variables declared within a range loop interact with variables declared outside the loop.
Consider the following code snippet:
{{ $prevDate := "" }} {{ range $post := .Posts }} {{ if ne $prevDate $post.Date }} <div>
The goal is to compare the current post's date with the previous post's date to display a section header when the date changes. However, the value of $prevDate seems to be reset to an empty string at the beginning of each iteration.
The issue lies in the scope of variables within the range loop. Each iteration of the loop creates a new shadowed variable $prevDate. This means that the value of $prevDate declared outside the loop is not modified, while the shadowed variable is modified within the loop.
Therefore, the problem can be solved by using the following alternatives:
Solution #1: Registered Function
Register a function that takes the current index and returns the date of the previous post, if available:
func PrevDate(i int) string { if i == 0 { return "" } return posts[i-1].Date }
Then, use the function in the template:
{{range $index, $post := .Posts}} {{$prevDate := PrevDate $index}} {{end}}
Solution #2: Method of Posts Type
Add a method to the Posts type to get the previous date:
func (p *Posts) PrevDate(i int) string { if i == 0 { return "" } return (*p)[i-1].Date }
Then, use the method in the template:
{{range $index, $post := .Posts}} {{$prevDate := $.Posts.PrevDate $index}} {{end}}
By using these solutions, the $prevDate variable can retain its value across iterations of the range loop, allowing you to compare post dates effectively.
The above is the detailed content of How to Properly Manage Variable Scope in Go Templates' Range Loops?. For more information, please follow other related articles on the PHP Chinese website!