为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
当年话下 2021-12-20 16:52:46
我正在遍历我的 API 响应并将其添加到这样的 html 模板中, // 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}我的印象是我应该能够像这样在我的 html 模板中调用它,{{.TopMovies}}但是当我运行应用程序时,数据没有出现在我调用它的 html 页面中。我在这里错过了什么?我创建了一个这样的结构,//A Page structuretype Page struct {  Title string  TopMovies string}然后在 main.go   http.HandleFunc("/TopPicks", TopMoviesHandler)TopPicks.html{{define "TopPicks"}}    {{template "header" .}}    <div class="content">    {{.TopMovies}}    </div>     {{template "footer" .}}    {{end}}这是什么工作,func aboutHandler(w http.ResponseWriter, r *http.Request) {  display(w, "about", &Page{Title: "About"})}我可以用与我之前提到的相同的方式向页面添加标题,但使用 display()并在 html 模板中<title>{{.Title}}</title>我怎样才能使我的 json 响应有效?
查看完整描述

2 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

我想你想要: t.ExecuteTemplate(w, "body", p)


话虽如此,如果您只想使用多个模板,您可以通过创建一个主顶级模板,然后将所有部分解析为子模板来实现。


这是一个示例(在 Play 上)。


轻松更改为遍历文件系统并加载所有模板,然后您只需执行与 http.Request 路径匹配的模板。


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)

    }

}


查看完整回答
反对 回复 2021-12-20
?
互换的青春

TA贡献1797条经验 获得超6个赞

好的,我认为原始代码有两个问题。


处理程序调用了错误的模板

func TopMoviesHandler(w http.ResponseWriter, r *http.Request) { ...snip 原代码...


err = t.ExecuteTemplate(w, "T", p) // This writes the client response


Should be 


err = t.ExecuteTemplate(w, "TopMovies", p) // This writes the client response

传递给嵌套模板的上下文不正确

在html文件中有这个代码


{{define "TopPicks"}}

     {{template "header" .}}

     <div class="content">

          {{.TopMovies}}

          {{template "MyTemplate" . }}

     </div>

     {{template "footer" .}}

{{end}}

哪个应该是


{{define "TopPicks"}}

     {{template "header" .}}

     <div class="content">

          {{.TopMovies}}

          {{template "MyTemplate" .TopMovies }}

     </div>

     {{template "footer" .}}

{{end}}

原因是您试图将主上下文传递给嵌套模板,而不是模板期望的 json 结果。


原答案


我做了一个我认为你需要做的简单例子。在我设置 topMovies 变量的地方,您可以在此处设置 api 调用的结果。我希望这有助于向您展示您需要更好地遵循的顺序。


package main


import (

    "net/http"

    "text/template"

)


type movie struct {

    Title string

}


type page struct {

    Title     string

    TopMovies []movie

}


func main() {

    http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {

        w.Header().Add("Content Type", "text/html")


        templates := template.New("template")

        templates.New("Body").Parse(doc)

        templates.New("List").Parse(docList)


        topMovies := []movie{{Title: "Movie 1"}, {Title: "Movie 2"}, {Title: "Movie 3"}}


        page := page{Title: "My Title", TopMovies: topMovies}

        templates.Lookup("Body").Execute(w, page)


    })


    http.ListenAndServe(":8000", nil)

}


const docList = `

<ul >

    {{range .}}

    <li>{{.Title}}</li>

    {{end}}

</ul>

`


const doc = `

<!DOCTYPE html>

<html>

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

    <body>

        <h1>Hello Templates</h1>

        {{template "List" .TopMovies}}

    </body>

</html>

`


查看完整回答
反对 回复 2021-12-20
  • 2 回答
  • 0 关注
  • 245 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信