dongyou7292 2018-08-20 00:58
浏览 496
已采纳

错误调用eq:Go模板中的比较类型无效

Background: a few static webpages share the same header. I am going to highlight the active header item by judging its state (in the Go template), with

<a href="/home" class="{{ if eq .Active "home"}} active{{end}}">Home</a>

which, in the terminal, ended up with

2018/08/19 16:46:49 template: _header.html:21:53: executing "_header.html" at <eq . "home">: error calling eq: invalid type for comparison

The error basically complained about undefined ".Active", which made me believe in failure with loading view models.
Here is the commit and repo. And I will show key files below:

_layout.html

<!DOCTYPE html>

<html>

<head>
    <title>{{.Title}}</title>
    <link href="/css/app.css" rel="stylesheet" /> {{block "styles" .}}{{end}}
</head>

<body>
    {{template "_header.html"}} {{template "content" .}} {{template "_footer.html"}}{{block "scripts" .}}{{end}}
</body>

</html>

_header.html

<header class="row">
    <div class="columns small-2">
        <div class="logo-container">
            <div class="logo"></div>
            <h1>Lemonade Stand Supply</h1>
        </div>
    </div>
    <div class="columns small-10">
        <div class="row">
            <div class="columns small-1 small-offset-9">
                <a class="secondary-color tiny" href="/login"> login </a>
            </div>
            <div class="columns small-2">
                <img src="/img/cart_small.png" alt="cart" />
            </div>
        </div>
        <div class="row">
            <nav class="columns small-6 small-offset-6">
                <div class="row">
                    <div class="columns small-3 item">
                        <a href="/home" class="{{ if eq .Active "home"}} active {{end}}">Home</a>
                    </div>
                    <div class="columns small-3 item">
                        <a href="/shop" class="{{ if eq .Active "shop"}} active {{end}}">Shop</a>
                    </div>
                    <div class="columns small-6 item">
                        <a href="." class="{{ if eq .Active "standlocator"}} active {{end}}">Stand Locator</a>
                    </div>
                </div>
            </nav>
        </div>
    </div>
</header>

main.go

package main

import (
    "html/template"
    "io/ioutil"
    "log"
    "net/http"
    "os"

    "TutorialCreatingWebApplicationsWithGo/src/github.com/lss/webapp/viewmodel"
)

func main() {
    templates := populateTemplates()
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        requestedFile := r.URL.Path[1:]
        template := templates[requestedFile+".html"]
        var context interface{}
        switch requestedFile {
        case "shop":
            context = viewmodel.NewShop()
        default:
            context = viewmodel.NewHome()
        }
        if template != nil {
            err := template.Execute(w, context)
            if err != nil {
                log.Println(err)
            }
        } else {
            w.WriteHeader(http.StatusNotFound)
        }
    })
    http.Handle("/img/", http.FileServer(http.Dir("../../../../public")))
    http.Handle("/css/", http.FileServer(http.Dir("../../../../public")))
    http.ListenAndServe(":8080", nil)
}

func populateTemplates() map[string]*template.Template {
    result := make(map[string]*template.Template)
    const basePath = "../../../../templates"
    layout := template.Must(template.ParseFiles(basePath + "/_layout.html"))
    template.Must(layout.ParseFiles(basePath+"/_header.html", basePath+"/_footer.html"))
    dir, err := os.Open(basePath + "/content")
    if err != nil {
        panic("Failed to open template blocks directory: " + err.Error())
    }
    fis, err := dir.Readdir(-1)
    if err != nil {
        panic("Failed to read contents of content directory: " + err.Error())
    }
    for _, fi := range fis {
        f, err := os.Open(basePath + "/content/" + fi.Name())
        if err != nil {
            panic("Failed to open template '" + fi.Name() + "'")
        }
        content, err := ioutil.ReadAll(f)
        if err != nil {
            panic("Failed to read content from file '" + fi.Name() + "'")
        }
        f.Close()
        tmpl := template.Must(layout.Clone())
        _, err = tmpl.Parse(string(content))
        if err != nil {
            panic("Failed to parse contents of '" + fi.Name() + "' as template")
        }
        result[fi.Name()] = tmpl
    }
    return result
}

view model - home.go

package viewmodel

type Home struct {
    Title  string
    Active string
}

func NewHome() Home {
    result := Home{
        Active: "home",
        Title:  "Lemonade Stand Supply",
    }
    return result
}

a view model - shop.go

package viewmodel

type Shop struct {
    Title      string
    Active     string
    Categories []Category
}

type Category struct {
    URL         string
    ImageURL    string
    Title       string
    Description string
}

func NewShop() Shop {
    result := Shop{
        Title:  "Lemonade Stand Supply - Shop",
        Active: "shop",
    }
    juiceCategory := Category{
        URL:      "/shop_details",
        ImageURL: "lemon.png",
        Title:    "Juices and Mixes",
        Description: `Explore our wide assortment of juices and mixes expected by today's
        lemonade stand clientelle. Now featuring a full line of organic juices that are guaranceed
        to be obtained from trees that have never been treated with pesticide or artificial fertilizers.`,
    }
    supplyCategory := Category{
        URL:      ".",
        ImageURL: "kiwi.png",
        Title:    "Cups, Straws, and Other Supplies",
        Description: `From paper cups to bio-degradable plastic to straws and napkins,
        LSS is your source for the sundries that keep you stand running smoothl.`,
    }
    advertiseCategory := Category{
        URL:      ".",
        ImageURL: "pineapple.png",
        Title:    "Signs and Advertising",
        Description: `Sure, you could just wait for people to find your stand along
        the side of the road, but if you want to take it to the next level, our premium
        line of advertising supplies.`,
    }
    result.Categories = []Category{juiceCategory, supplyCategory, advertiseCategory}
    return result
}

This is literal follow up with the course Creating Web Application with Go by Mike Van Sickle (module 5.7, Logical Tests) . Having carefully matched each file with the example code provided by the lecturer (which worked perfectly fine), I found the code were the same and still cannot find the cause to the problem.

  • 写回答

1条回答 默认 最新

  • 普通网友 2018-08-20 02:32
    关注

    Change your template/_layout.html to this

    <!DOCTYPE html>
    <html>
    <head>
    <title>{{.Title}}</title>
    <link href="/css/app.css" rel="stylesheet" />
    {{block "styles" .}}{{end}}
    </head>
    <body>
        {{template "_header.html" .}}
        {{template "content" .}}
        {{template "_footer.html" .}}
        {{block "scripts" .}}{{end}}
    </body>
    </html>
    

    Your base template was not correct and that's why you are getting this error.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵