在Golang模板中获取结构体中数组的最后一个元素。

huangapple go评论141阅读模式
英文:

Get the last element of an array within a struct in a Golang template

问题

我正在为一个学校项目使用Go语言构建一个简单的论坛,我正在将一个数据结构传递给模板,以显示子论坛中的所有帖子。我传递给模板的数据如下:

type Data struct {
   ID    int       // 子论坛的ID
   User  User      // 登录的用户
   Posts []Post    // 子论坛的所有帖子
}

Data结构中的Post结构如下:

type Post struct {
	ID         int
	Title      string
	Content    string
	Date       time.Time
	[...]
	Author     User
	Comments   []Comment
}

Comment结构与Post结构类似。当我显示所有帖子的列表时,我还想显示回复的数量和最后回复的日期/时间。

在我的HTML模板中,我可以通过以下方式获取回复的数量:

{{range .Posts}}
    <p>Replies: {{ len .Comments }}</p>
{{ end }}

...但是我似乎无法理解如何获取Comments数组的最后一个元素的日期。我知道可以使用index关键字和值'0'来获取第一个元素,但是我无法在模板中使用**(len .Comments -1)**来获取最后一个元素,因为'-'是一个禁止的字符。我可能会在我的SQLite数据库中创建一个第二个函数,以按降序获取我的评论,但我想知道在Go模板中是否有一种简单的方法来处理索引。

谢谢。

英文:

I'm building a simple forum in Go for a school project, and I'm passing a data struct to a template to display all the posts in a subforum. The data I'm passing to the template is this:

type Data struct {
   ID    int       // ID of the subforum
   User  User      // logged-in user
   Posts []Post    // all the posts of the subforum
}

The Post struct within the Data struct is like this:

type Post struct {
	ID         int
	Title      string
	Content    string
	Date       time.Time
	[...]
	Author     User
	Comments   []Comment
}

And the Comment struct is similar to the Post struct. When I display the list of all the posts, I would like to also show the number of replies and the date/time of the last reply.

In my HTML template, I can get the number of replies like this:

{{range .Posts}}

    &lt;p&gt;Replies: {{ len .Comments }}&lt;/p&gt;

{{ end }}

...but I can't seem to get my head around getting the date of the last element of the Comments array. I know you can get the first element with the index keyword and the value '0', but I can't use (len .Comments -1) inside the template to get the last element as '-' is a forbidden character. I'll probably just make a second function to get my comments sorted by descending order from my SQLite database, but I was wondering if there was a simple way to work with the indexes in Go templates.

Thank you.

答案1

得分: 3

在Go模板中没有一种干净的方法来实现这一点,但是有一个解决方法在这里。一个更简单的解决方法是在将结构体传递给模板之前,将最后一个项目添加到你的结构体中。你所做的是将复杂的逻辑从模板中移出(模板本来就不是为此设计的),并将其放入Go代码中。

type Post struct {
    ....
    Comments   []Comment
    LastComment Comment
}

然后在你的模板中,只需使用:

{{ .LastComment }}
英文:

There's not a clean way to do this with Go templates, however this is a workaround here. A simpler workaround would be to add the last item to your struct before passing the struct to the templater. What you're doing is moving the complicated logic out of the template (templates weren't designed to do this anyways) and into the Go code.

type Post struct {
    ....
    Comments   []Comment
    LastComment Comment
}

Then in your template, just do

{{ .LastComment }}

答案2

得分: 2

你可以在模板中使用自定义函数来获取最后一个元素:

fmap := template.FuncMap{
    "lastElem": func(comments []Comment) Comment { 
        return comments[len(comments)-1]
    },
}

tmpl, err := template.New("tmpl").Funcs(fmap).Parse(tpl)

然后在模板中使用它:

{{range .Posts}}

    <p>回复{{ lastElem .Comments }}</p>

{{ end }}
英文:

You can use a custom function inside your template to get the last element:

fmap := template.FuncMap{
    &quot;lastElem&quot;: func(comments []Comment) Comment { 
        return comments[len(comments)-1]
    },
}

tmpl, err := template.New(&quot;tmpl&quot;).Funcs(fmap).Parse(tpl)

And then use it in your template as:

{{range .Posts}}

    &lt;p&gt;Replies: {{ lastElem .Comments }}&lt;/p&gt;

{{ end }}

huangapple
  • 本文由 发表于 2021年6月5日 00:26:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/67840797.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定