Embedding Go

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 .

 Share!

 
comments powered by Disqus