在golang的HTML模板中,如何在{{range .}}范围之外访问结构变量?

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

Accessing struct variable outside of {{range .}} scope in golang html template

问题




测试

回复





{{range .}}
{{$threadID := .ThreadID}}

{{.Subject}}

{{.Name}}

{{.DatePosted}}

{{.Text}}

{{end}}


我有这个模板,在页面顶部有一个表单,需要从发送的任何一个帖子中获取threadID(它们都是相同的,是具有特定threadID的所有帖子的切片),这显然行不通,我唯一的其他想法是类似于

{{range .}}
{{if $threadID == nil}}
$threadID := .ThreadID
//构建与上面相同的表单
{{end}}

{{.Subject}}

{{.Name}}

{{.DatePosted}}

{{.Text}}

{{end}}

如果上面的任何内容不清楚,这是Post结构和方法。

type Post struct {
threadID int
subject string
name string
text string
date_posted string
}

func (p *Post) ThreadID() int { return p.threadID }
func (p *Post) Subject() string { return p.subject }
func (p *Post) Name() string { return p.name }
func (p *Post) Text() string { return p.text }
func (p *Post) DatePosted() string { return p.date_posted }

以及发送到模板的帖子切片的来源。

threadID := r.URL.Path[len("/reply/"):]
replies, err := i.db.Query("SELECT * FROM latest_threads where thread_id="+threadID);

英文:
<!DOCTYPE html>
<html>
<head>
	<title> Test </title>
</head>
<body>
	<div>
		<h2>Reply</h2>
		<form action="/post/{{$threadID}}" method="POST">
		<input type="text" name="subject" />
		<input type="text" name="name" value="Anonymous" />
		<input type="text" name="message" />
		<input type="submit" value="submit" />
		</form>
	</div>
	<div>
		{{range .}}
		{{$threadID := .ThreadID}}
		<h3>{{.Subject}}</h3>
		<h3>{{.Name}}</h3>
		<div>{{.DatePosted}}</div>
		<div><p>{{.Text}}</p></div>
		<br /><br />
		{{end}}
	</div>
</body>

</html>

I have this template, there is a form at the top of the page that requires the threadID from ANY one of the Posts sent (they're all the same, a slice of all posts with a certain threadID), this obviously doesn't work, my only other idea was something along the lines of

{{range .}}
    {{if $threadID == nil}}
        $threadID := .ThreadID
        //build the form same as above
    {{end}}
    &lt;h3&gt;{{.Subject}}&lt;/h3&gt;
    &lt;h3&gt;{{.Name}}&lt;/h3&gt;
    &lt;div&gt;{{.DatePosted}}&lt;/div&gt;
    &lt;div&gt;&lt;p&gt;{{.Text}}&lt;/p&gt;&lt;/div&gt;
    &lt;br /&gt;&lt;br /&gt;
{{end}}

Here is the Post structure and methods if any of the above is unclear.

type Post struct {
threadID int
subject string
name string
text string
date_posted string
}

func (p *Post) ThreadID()   int    { return p.threadID    }
func (p *Post) Subject()    string { return p.subject     }
func (p *Post) Name()       string { return p.name        }
func (p *Post) Text()       string { return p.text        }
func (p *Post) DatePosted() string { return p.date_posted } 

And the origin of the slice of posts sent to the template

threadID := r.URL.Path[len(&quot;/reply/&quot;):]
replies, err := i.db.Query(&quot;SELECT * FROM latest_threads where thread_id=&quot;+threadID);

答案1

得分: 5

如果只能从帖子类型本身中获取线程ID,请考虑将帖子列表转换为单独的类型。给它一个ThreadId方法,该方法简单地返回它包含的第一个帖子的ID,如果没有帖子存在,则返回零。

type PostList []*Post

func (p PostList) ThreadId() int {
    if len(p) == 0 {
        return 0
    }
    return p[0].ThreadId
}

将此列表传递到模板中。现在,您可以在模板中的{{range .}}之外的任何地方引用它。

<form action="/post/{{.ThreadID}}" method="POST">

漏洞警告

顺便提一下,Little Bobby Tables在SQL查询中存在问题。如果您只是将其作为一个快速示例发布,那么可能没有问题。如果不是,请注意您的代码可能会导致SQL注入攻击。如果线程ID是数字,请确保在将其传递到SQL查询之前将其解析为数字。例如:对输入进行清理处理。

英文:

If the Thread Id can only be retrieved from the Post type itself, consider turning your slice of posts into a separate type. Give it a ThreadID method, which simply returns the id for the first post it contains, or zero if none exist.

type PostList []*Post

func (p PostList) ThreadId() int {
    if len(p) == 0 {
        return 0
    }
    return p[0].ThreadId
}

Pass this list into the template. Now you can reference it from the template, anywhere outside of the {{range .}} clause.

&lt;form action=&quot;/post/{{.ThreadID}}&quot; method=&quot;POST&quot;&gt;

Exploit warning

As a side note, Little Bobby Tables has an issue with the SQL query.
It's possible you are just posting it as a quick example. If not, be advised that your code is a recipe for SQL injection exploits. If the thread ID is numeric, then ensure you parse it as such, before passing it into the SQL query. E.g.: Sanitize your inputs.

答案2

得分: 4

你可以将所有内容作为一个结构体传递,如下所示:

layoutData := struct {
    ThreadID int
    Posts []Post
} {
    ThreadID: threadID,
    Posts: Posts,
}

然后可以使用以下代码:

<!DOCTYPE html>
<html>
<head>
    <title> Test </title>
</head>
<body>
    <div>
        <h2>Reply</h2>
        <form action="/post/{{ .ThreadID }}" method="POST">
        <input type="text" name="subject" />
        <input type="text" name="name" value="Anonymous" />
        <input type="text" name="message" />
        <input type="submit" value="submit" />
        </form>
    </div>
    <div>
        {{range $post := .Posts}}
        <h3>{{$post.Subject}}</h3>
        <h3>{{$post.Name}}</h3>
        <div>{{$post.DatePosted}}</div>
        <div><p>{{$post.Text}}</p></div>
        <br /><br />
        {{end}}
    </div>
</body>

请注意,这只是一个示例代码,具体实现可能需要根据你的需求进行调整。

英文:

You can pass it all as one struct like so:

layoutData := struct {
    ThreadID int
    Posts []Post
} {
    ThreadID: threadID,
    Posts: Posts,
}

Then something like this will work

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt; Test &lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div&gt;
        &lt;h2&gt;Reply&lt;/h2&gt;
        &lt;form action=&quot;/post/{{ .ThreadID }}&quot; method=&quot;POST&quot;&gt;
        &lt;input type=&quot;text&quot; name=&quot;subject&quot; /&gt;
        &lt;input type=&quot;text&quot; name=&quot;name&quot; value=&quot;Anonymous&quot; /&gt;
        &lt;input type=&quot;text&quot; name=&quot;message&quot; /&gt;
        &lt;input type=&quot;submit&quot; value=&quot;submit&quot; /&gt;
        &lt;/form&gt;
    &lt;/div&gt;
    &lt;div&gt;
        {{range $post := .Posts}}
        &lt;h3&gt;{{ $post.Subject}}&lt;/h3&gt;
        &lt;h3&gt;{{$post.Name}}&lt;/h3&gt;
        &lt;div&gt;{{$post.DatePosted}}&lt;/div&gt;
        &lt;div&gt;&lt;p&gt;{{$post.Text}}&lt;/p&gt;&lt;/div&gt;
        &lt;br /&gt;&lt;br /&gt;
        {{end}}
    &lt;/div&gt;
&lt;/body&gt;

huangapple
  • 本文由 发表于 2014年3月13日 08:26:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/22366725.html
匿名

发表评论

匿名网友

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

确定