This is a simple package that makes rendering Go html templates as painless as possible. It has no dependencies outside of the standard library.
Install it the usual way:
go get -u github.com/tsawler/page
To use, import github.com/tsawler/page
, and create a variable of type page.Render
, either by
using the New() method, or by manually constructing the variable.
At the minimum, you must specify the directory where your templates live with the TemplateDir
field, and
a list of partials you want to include, with the Partials
field.
If you set UseCache to true, then every time a template is rendered it will be stored in the TemplateMap
field,
which is of type map[string]*template.Template
. This way, pre-parsed templates can be read very quickly from
memory, rather than rebuilding them from disk on every request, which is an expensive operation.
Assuming that you have two Go templates named base.layout.gohtml
and home.page.gohtml
which look like this...
{{define "base"}}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
{{block "content" .}}
{{end}}
</body>
</html>
{{end}}
{{template "base" .}}
{{define "content"}}
<h1>Hello, world!</h1>
<p>{{index .Data "payload"}}</p>
{{end}}
... then you can use code like this:
package main
import (
"fmt"
"html/template"
"log"
"net/http"
"github.com/tsawler/page"
)
const port = ":8080"
type Data struct {
Data map[string]any
}
func main() {
render := page.Render{
TemplateDir: "./templates",
TemplateMap: make(map[string]*template.Template),
Functions: template.FuncMap{},
Debug: true,
UseCache: true,
}
// Call LoadLayoutsAndPartials to automatically load all such files in TemplateDir.
err := render.LoadLayoutsAndPartials([]string{".layout"})
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
data := make(map[string]any)
data["payload"] = "This is passed data."
err := render.Show(w, "home.page.gohtml", &Data{Data: data})
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
log.Println(err)
return
}
})
http.HandleFunc("/string", func(w http.ResponseWriter, r *http.Request) {
data := make(map[string]any)
data["payload"] = "This is passed data."
out, err := render.String("home.page.gohtml", &Data{Data: data})
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
log.Println(err)
return
}
log.Println(out)
fmt.Fprint(w, "Check the console; you should see html")
})
log.Println("Starting on port", port)
err = http.ListenAndServe(port, nil)
if err != nil {
log.Fatal(err)
}
}