So far, the templates that I have been using reside in the templates directory from my localhost, which means of course, that if I shipped my binary and try to execute it in a different PC (or even the same PC but different directory), it will fail because it will not find the contact, faq and home.gohtml files. For reference:
└── section-6
├── controllers
│ └── static.go
├── go.mod
├── go.sum
├── main.go
├── templates
│ ├── contact.gohtml
│ ├── faq.gohtml
│ └── home.gohtml
└── views
└── template.go
So, “embedding” can be used to overcome this.
package templates
import "embed"
//go:embed *.gohtml
var SF embed.FS
I added it here:
├── templates
│ ├── contact.gohtml
│ ├── faq.gohtml
│ ├── fs.go <------------- Here. "fs" as in file system.
│ └── home.gohtml
Next, for the template.go I will need to add the following function:
func ParseFS(fs fs.FS, pattern string) (Template, error) {
tpl, err := template.ParseFS(fs, pattern)
if err != nil {
return Template{}, fmt.Errorf("parsing template: %w", err)
}
return Template{
htmlTpl: tpl,
}, nil
}
And, finally everything can be called from main.go:
package main
import (
"fmt"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/rabocse/lenslocked/controllers"
"github.com/rabocse/lenslocked/templates"
"github.com/rabocse/lenslocked/views"
)
func main() {
r := chi.NewRouter()
r.Get("/", controllers.StaticHandler(views.Must(views.ParseFS(templates.FS, "home.gohtml"))))
r.Get("/contact", controllers.StaticHandler(views.Must(views.ParseFS(templates.FS, "contact.gohtml"))))
r.Get("/faq", controllers.StaticHandler(views.Must(views.ParseFS(templates.FS, "faq.gohtml"))))
r.NotFound(func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Page Not Found", http.StatusNotFound)
})
fmt.Println("Starting the server on :3000...")
http.ListenAndServe(":3000", r)
}
At this point, I can build a binary that contains the embedded .gohtml files:
go build -o app .