英文:
Golang code to repeat an html code n times
问题
我正在使用golang开发web应用程序。在其中,我需要将HTML行迭代n
次。
func index(w http.ResponseWriter, r *http.Request) {
tmpl := template.Must(template.ParseFiles("templates/index.html"))
n := 5
tmpl.Execute(w, n)
}
<ul>
<li><a href="/?page=1">1</a></li>
<li><a href="/?page=2">2</a></li>
.
.
.
<li><a href="/?page=n">n</a></li>
</ul>
你想知道如何实现这个功能吗?
英文:
I am working on golang web app. In that I need to iterate an HTML line n
number of times.
func index(w http.ResponseWriter, r *http.Request) {
tmpl := template.Must(template.ParseFiles("templates/index.html"))
n := 5
tmpl.Execute(w, n)
}
<ul>
<li><a href="/?page=1">1</a></li>
<li><a href="/?page=2">2</a></li>
.
.
.
<li><a href="/?page=n">n</a></li>
</ul>
How can I implement this?
答案1
得分: 11
要在Go模板中重复某个内容,可以使用{{range}}
操作。但是{{range}}
操作需要一个可迭代的对象,例如切片、数组或映射。
传递一个零值切片
因此,您需要提供一个可迭代的对象。但是,只需要占用内存的空切片就足够了,例如make([]struct{}, n)
。
模板代码:
const templ = `<ul>
{{range $idx, $e := .}}
<li><a href="/?page={{$idx}}">{{$idx}}</a></li>
{{end}}
</ul>`
测试代码:
tmpl := template.Must(template.New("").Parse(templ))
n := 5
if err := tmpl.Execute(os.Stdout, make([]struct{}, n)); err != nil {
panic(err)
}
输出结果(在Go Playground上尝试):
<ul>
<li><a href="/?page=0">0</a></li>
<li><a href="/?page=1">1</a></li>
<li><a href="/?page=2">2</a></li>
<li><a href="/?page=3">3</a></li>
<li><a href="/?page=4">4</a></li>
</ul>
使用填充的切片
如我们所见,索引从0开始。如果这是一个问题,您可以选择不使用索引,而是显式地使用您想要的元素填充传递的切片。然后,模板将如下所示:
const templ = `<ul>
{{range .}}
<li><a href="/?page={{.}}">{{.}}</a></li>
{{end}}
</ul>`
下面是一个示例测试代码,它只使用从2
开始的奇数填充切片:
tmpl := template.Must(template.New("").Parse(templ))
n := 5
values := make([]int, n)
for i := range values {
values[i] = (i + 1) * 2
}
if err := tmpl.Execute(os.Stdout, values); err != nil {
panic(err)
}
这次的输出结果(在Go Playground上尝试):
<ul>
<li><a href="/?page=2">2</a></li>
<li><a href="/?page=4">4</a></li>
<li><a href="/?page=6">6</a></li>
<li><a href="/?page=8">8</a></li>
<li><a href="/?page=10">10</a></li>
</ul>
使用零值切片和自定义函数
如果您不想麻烦地填充切片,并且只需要从1开始递增的数字,另一种选择是注册一个函数,该函数接收一个数字,将其加1并返回结果。因此,您可以继续使用零值切片的索引,并且可以调用自定义函数以获得等于索引+1的数字:
func main() {
tmpl := template.Must(template.New("").Funcs(template.FuncMap{
"Add": func(i int) int { return i + 1 },
}).Parse(templ))
n := 5
if err := tmpl.Execute(os.Stdout, make([]struct{}, n)); err != nil {
panic(err)
}
}
const templ = `<ul>
{{range $idx, $e := .}}{{$idx := (Add $idx)}}
<li><a href="/?page={{$idx}}">{{$idx}}</a></li>
{{end}}
</ul>`
这次的输出结果(在Go Playground上尝试):
<ul>
<li><a href="/?page=1">1</a></li>
<li><a href="/?page=2">2</a></li>
<li><a href="/?page=3">3</a></li>
<li><a href="/?page=4">4</a></li>
<li><a href="/?page=5">5</a></li>
</ul>
英文:
To repeat something in Go templates, you may use the {{range}}
action. But the {{range}}
action expects something it can iterate over, e.g. a slice, array or map.
Passing a zero-value slice
So you have to feed that. But an empty slice which requires no memory is sufficient, e.g. make([]struct{}, n)
.
The template code:
const templ = `<ul>
{{range $idx, $e := .}}
<li><a href="/?page={{$idx}}">{{$idx}}</a></li>
{{end}}
</ul>`
Testing it:
tmpl := template.Must(template.New("").Parse(templ))
n := 5
if err := tmpl.Execute(os.Stdout, make([]struct{}, n)); err != nil {
panic(err)
}
Output (try it on the Go Playground):
<ul>
<li><a href="/?page=0">0</a></li>
<li><a href="/?page=1">1</a></li>
<li><a href="/?page=2">2</a></li>
<li><a href="/?page=3">3</a></li>
<li><a href="/?page=4">4</a></li>
</ul>
Using a filled slice
As we can see, indices start from 0. If this is an issue, you may opt to not use the index, but fill the passed slice explicitly with the elements you want. Then the template will look like this:
const templ = `<ul>
{{range .}}
<li><a href="/?page={{.}}">{{.}}</a></li>
{{end}}
</ul>`
And an example test code that feeds only the odd numbers starting with 2
could look like this:
tmpl := template.Must(template.New("").Parse(templ))
n := 5
values := make([]int, n)
for i := range values {
values[i] = (i + 1) * 2
}
if err := tmpl.Execute(os.Stdout, values); err != nil {
panic(err)
}
Output this time (try it on the Go Playground):
<ul>
<li><a href="/?page=2">2</a></li>
<li><a href="/?page=4">4</a></li>
<li><a href="/?page=6">6</a></li>
<li><a href="/?page=8">8</a></li>
<li><a href="/?page=10">10</a></li>
</ul>
Using a zero-valued slice and custom function
If you don't want to bother filling the slice and you only need increasing numbers starting from 1, another option would be to register a function that receives a number, adds 1 to it and returns the result. So you may continue to use the indices of a zero-valued slice, and you can call the custom function to obtain a number equal to index+1:
func main() {
tmpl := template.Must(template.New("").Funcs(template.FuncMap{
"Add": func(i int) int { return i + 1 },
}).Parse(templ))
n := 5
if err := tmpl.Execute(os.Stdout, make([]struct{}, n)); err != nil {
panic(err)
}
}
const templ = `<ul>
{{range $idx, $e := .}}{{$idx := (Add $idx)}}
<li><a href="/?page={{$idx}}">{{$idx}}</a></li>
{{end}}
</ul>`
Output this time (try it on the Go Playground):
<ul>
<li><a href="/?page=1">1</a></li>
<li><a href="/?page=2">2</a></li>
<li><a href="/?page=3">3</a></li>
<li><a href="/?page=4">4</a></li>
<li><a href="/?page=5">5</a></li>
</ul>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论