Access to struct variable outside of {{range.}} Scope in golang holml template

<!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> 

I have this template, at the top of the page there is a form that requires threadID from ANY one of the sent messages (they are all the same, a slice of all messages with a specific stream identifier), this obviously does not work, my only other idea was something like

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

Here is the Post structure and methods if any of the above issues are 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 beginning of the fragment of messages sent to the template

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

You can pass all this as one structure, for example:

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

Then something like this will work

 <!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> 
+3
source

If the thread ID can only be obtained from the Post type itself, consider moving a slice of messages to a separate type. Give it a ThreadID method that simply returns the identifier for the first post it contains, or zero if it does not exist.

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

Pass this list to the template. Now you can refer to it from the template, anywhere outside the {{range .}} .

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

Usage Warning

As a side note, Small Bobby tables have a problem with the SQL query. Perhaps you are just posting it as a quick example. If not, let your code be a recipe for SQL injection exploits . If the stream identifier is numeric, make sure that you parse it as such before passing it to the SQL query. For example: sanitize your inputs.

+5
source

All Articles