简体   繁体   中英

HTML Form Submission in golang template

I am using the go language to submit an HTML form using the go-template. Getting some weird results.

The basic idea is that I have a data structure called Page containing a few elements. The template is populated with an array of Pages. Inside the template I iterate through each Page and display its contents. Each of these contents are embedded inside an HTML form with its respective link. Once the link is clicked it will submit the respective form.

The code snippet is as follows:

{{range $index, $element := .Pages}}                                                                            
  <form action="/detailNews" id="readMore{{$index}}" method="post" name="readMore{{$index}}">
    //displaying elements from each page                    

    <div id="more">
      <input name="query" type="hidden" value="{{printf "%s" .Title}}">                         
      <a href="#" onclick="document.readMore{{$index}}.submit()">Read More</a>
    </div>

  </form>
{{end}}

The code mostly works with one little problem. The id and the name attributes generate outputs as expected such as: readMore0 , readMore1 , etc.

The problem is at the "a" tag where the onclick attribute is populated with this: document.readMore 0 .submit() , document.readMore 1 .submit() , etc. Note the space surrounding 0, 1. With this, the respective form is not being found when the link is clicked.

I can't figure out the reason of this.

Any help will be highly appreciated.

Thanks, Ripul

This is happening because of escaping contexts .

By default, this package assumes that all pipelines produce a plain text string. It adds escaping pipeline stages necessary to correctly and safely embed that plain text string in the appropriate context.

When a data value is not plain text, you can make sure it is not over-escaped by marking it with its type.

Types HTML, JS, URL, and others from content.go can carry safe content that is exempted from escaping.

In order to overcome it you should pass the page index as part of the .Pages element structs typed as template.JS . Something like this :

type Page struct {
         Id    template.JS
         Title string
}

Do you have a working example to reproduce? I tried locally and it works as expected:

http://play.golang.org/p/ZnM0RqIMfL

package main

import (
        "os"
        "text/template"
)

type Page struct {
        Title string
}

func main() {
        template.Must(template.New("test").Parse(`
{{range $index, $element := .Pages}}
  <form action="/detailNews" id="readMore{{$index}}" method="post" name="readMore{{$index}}">
    //displaying elements from each page

    <div id="more">
      <input name="query" type="hidden" value="{{printf "%s" .Title}}">
      <a href="#" onclick="document.readMore{{$index}}.submit()">Read More</a>
    </div>

  </form>
{{end}}
`)).Execute(os.Stdout, struct{ Pages []Page }{Pages: []Page{
                {Title: "page1"}, {Title: "page2"},
        }})
}

Result:

 <form action="/detailNews" id="readMore0" method="post" name="readMore0">
    //displaying elements from each page

    <div id="more">
      <input name="query" type="hidden" value="page1">
      <a href="#" onclick="document.readMore0.submit()">Read More</a>
    </div>

  </form>

  <form action="/detailNews" id="readMore1" method="post" name="readMore1">
    //displaying elements from each page

    <div id="more">
      <input name="query" type="hidden" value="page2">
      <a href="#" onclick="document.readMore1.submit()">Read More</a>
    </div>

  </form>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM