doufen1890 2016-03-12 13:25
浏览 250
已采纳

在GoLang中将Json数据映射到HTML模板

I am looping through my API response and adding it to the html template like this,

 // Following sends same information as above to the browser as html
     t, err := template.New("TopMovies").Parse(`
      {{define "TopMovies"}}
        <html>
        <ul>
        {{$ImgUrl := "http://image.tmdb.org/t/p/w185" }}
        {{range $movies := .Results}}
        <li>{{$ImgUrl}}{{$movies.PosterPath}}</li>
        <li>{{$movies.Adult}}</li>
        <li>{{$movies.Overview}}</li>
        <li>{{$movies.ReleaseDate}}</li>
        <li>{{$movies.GenreIds}}</li>
        <li>{{$movies.Id}}</li>
        <li>{{$movies.OriginalTitle}}</li>
        <li>{{$movies.OriginalLanguage}}</li>
        <li>{{$movies.Title}}</li>
        <li>{{$ImgUrl}}{{$movies.BackdropPath}}</li>
        <li>{{$movies.Popularity}}</li>
        <li>{{$movies.VoteCount}}</li>
        <li>{{$movies.Video}}</li>
        <li>{{$movies.VoteAverage}}</li>
        {{end}}
        </ul>
        </html>
      {{end}}
      `)
    err = t.ExecuteTemplate(w, "T", p) // This writes the client response
}

I am under the impression I should be able to call this in my html templates like this,

{{.TopMovies}}

But when I run the app the data does not appear in the html page I am calling it in. What am I missing here?

I create a struct like this,

//A Page structure
type Page struct {
  Title string
  TopMovies string
}

Then I create my handle like this,

func TopMoviesHandler(w http.ResponseWriter, r *http.Request) {
   res, err := http.Get(url)
      if err != nil {
        panic(err)
      }
      defer res.Body.Close()

      body, err := ioutil.ReadAll(res.Body)
      if err != nil {
        panic(err)
      }
      var p Payload

      err = json.Unmarshal(body, &p)
      if err != nil {
        panic(err)
      }

  // Following sends same information as above to the browser as html
     t, err := template.New("TopMovies").Parse(`
      {{define "TopMovies"}}
        <html>
        <ul>
        {{$ImgUrl := "http://image.tmdb.org/t/p/w185" }}
        {{range $movies := .Results}}
        <li>{{$ImgUrl}}{{$movies.PosterPath}}</li>
        <li>{{$movies.Adult}}</li>
        <li>{{$movies.Overview}}</li>
        <li>{{$movies.ReleaseDate}}</li>
        <li>{{$movies.GenreIds}}</li>
        <li>{{$movies.Id}}</li>
        <li>{{$movies.OriginalTitle}}</li>
        <li>{{$movies.OriginalLanguage}}</li>
        <li>{{$movies.Title}}</li>
        <li>{{$ImgUrl}}{{$movies.BackdropPath}}</li>
        <li>{{$movies.Popularity}}</li>
        <li>{{$movies.VoteCount}}</li>
        <li>{{$movies.Video}}</li>
        <li>{{$movies.VoteAverage}}</li>
        {{end}}
        </ul>
        </html>
      {{end}}
      `)
    err = t.ExecuteTemplate(w, "T", p) // This writes the client response
}

Then in main.go

   http.HandleFunc("/TopPicks", TopMoviesHandler)

TopPicks.html

{{define "TopPicks"}}
    {{template "header" .}}
    <div class="content">
    {{.TopMovies}}
    </div>
     {{template "footer" .}}
    {{end}}

What does work is this,

func aboutHandler(w http.ResponseWriter, r *http.Request) {
  display(w, "about", &Page{Title: "About"})
}

I can add a title to the page in the same way as I previously mentioned but using display()

And in the html template

<title>{{.Title}}</title>

How can I make this work for my json response?

  • 写回答

2条回答 默认 最新

  • douzen1880 2016-03-12 15:53
    关注

    Looks like you are doing {{define "body"}}, but then asking ExecuteTemplate to execute "T" which isn't defined anywhere.

    I think you want: t.ExecuteTemplate(w, "body", p)

    That all said, if you just want to use multiple templates, you can do it by creating a master top level template, then parsing all the parts as sub templates.

    Here's an example (on Play).

    Easily changed to walk your file system and load all your templates, then you just execute the template matching the http.Request path.

    package main
    
    import "html/template"
    import "os"
    import "log"
    
    var mainText = `
    Normal page stuff
    {{ template "_header_" . }}
    {{ template "body" . }}
    `
    
    var bodyText = `
     Body has: {{ .Thing }}
    `
    var headerText = `
     I am header text
    `
    
    type Stuff struct {
        Thing string
    }
    
    func main() {
        t := template.New("everything")
    
        // parse all templates you may want
        template.Must(t.New("/").Parse(mainText))
        template.Must(t.New("_header_").Parse(headerText))
        template.Must(t.New("body").Parse(bodyText))
    
        if err := t.ExecuteTemplate(os.Stdout, "/", Stuff{"I am a thing"}); err != nil {
            log.Fatal("Failed to execute:", err)
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 gwas 分析-数据质控之过滤稀有突变中出现的问题
  • ¥15 没有注册类 (异常来自 HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
  • ¥15 知识蒸馏实战博客问题
  • ¥15 用PLC设计纸袋糊底机送料系统
  • ¥15 simulink仿真中dtc控制永磁同步电机如何控制开关频率
  • ¥15 用C语言输入方程怎么
  • ¥15 网站显示不安全连接问题
  • ¥15 51单片机显示器问题
  • ¥20 关于#qt#的问题:Qt代码的移植问题
  • ¥50 求图像处理的matlab方案