user3140645
user3140645

Reputation: 15

Trouble with the HTML() function in Golang's "html/template" package

I am having an issue with getting the "html/template" package to parse a template properly. I am trying to parse in HTML content to a template page that I have made, however, when I try, the parsed page ends up with the escaped HTML instead of the actual code I want.

The Go documentation says I can simply use the HTML() function to convert a string into a type HTML, which is known to be safe and should be parsed in as HTML. I have made my Content field in my type Page a template.HTML, which compiles just fine, but when I use the template.HTML(content) function in line 53, I get a compiler error saying:

template.HTML undefined (type *"html/template".Template has no field or method HTML)

Using HTML(content) (without the preceding template.) results in this error:

undefined: HTML

My end goal is to have other HTML files parse into index.html and be interpreted by the browser as HTML.

Any help is appreciated.

package main

import (
    "fmt"
    "html/template"
    "io"
    "io/ioutil"
    "net/http"
    "regexp"
    "strings"
)

func staticServe() {
    http.Handle(
        "/assets/",
        http.StripPrefix(
            "/assets/",
            http.FileServer(http.Dir("assets")),
        ),
    )
}

var validPath = regexp.MustCompile("^/(|maps|documents|residents|about|source)?/$")


//  This shit is messy. Clean it up.

func servePage(res http.ResponseWriter, req *http.Request) {
    type Page struct {
        Title   string
        Content template.HTML
    }

    pathCheck := validPath.FindStringSubmatch(req.URL.Path)
    path := pathCheck[1]
    fmt.Println(path)

    if path == "" {
        path = "home"
    }

    template, err := template.ParseFiles("index.html")
    if err != nil {
        fmt.Println(err)
    }

    contentByte, err := ioutil.ReadFile(path + ".html")
    if err != nil {
        fmt.Println(err)
    }
    content := string(contentByte)

    page := Page{strings.Title(path) + " - Tucker Hills Estates", template.HTML(content)}

    template.Execute(res, page)
}

//  Seriously. Goddamn.

func serveSource(res http.ResponseWriter, req *http.Request) {
    sourceByte, err := ioutil.ReadFile("server.go")
    if err != nil {
        fmt.Println(err)
    }
    source := string(sourceByte)
    io.WriteString(res, source)
}

func main() {
    go staticServe()
    http.HandleFunc("/", servePage)
    http.HandleFunc("/source/", serveSource)
    http.ListenAndServe(":9000", nil)
}

Upvotes: 0

Views: 2548

Answers (2)

justinas
justinas

Reputation: 6847

Having imported "html/template" earlier, this line

template, err := template.ParseFiles("index.html")

shadows the template package, so when you do template.HTML later on, you're looking for HTML attribute on the template object, not for something called HTML in the package.

To prevent this, change the name of your variable.

tmpl, err := template.ParseFiles("index.html")

Upvotes: 8

Eve Freeman
Eve Freeman

Reputation: 33145

You are shadowing your package with a variable called template. The easiest fix is probably to change your variable name to tmpl or something.

Upvotes: 0

Related Questions