Skip to content

Instantly share code, notes, and snippets.

@inhies
Last active October 13, 2023 22:21
Show Gist options
  • Save inhies/f5b0592b3dc8195aa5a3d551db96496d to your computer and use it in GitHub Desktop.
Save inhies/f5b0592b3dc8195aa5a3d551db96496d to your computer and use it in GitHub Desktop.
A basic web server that will serve templates and reload them when they are changed on disk
package main
import (
"fmt"
"html/template"
"io/ioutil"
"log"
"net/http"
"strings"
"gopkg.in/fsnotify.v1"
)
var (
templateDir = "./webui/templates"
staticDir = "./webui/static"
reloadTemplates bool
routes = map[string]http.HandlerFunc{
"/": rootHandler,
}
t *template.Template
cwd string
pages = map[string]Page{
"index": indexPage{
Title: "Index",
},
}
)
type Page interface{}
type indexPage struct {
Title string
}
func init() {
watcher, err := fsnotify.NewWatcher()
if err != nil {
fmt.Println(err)
}
// Process events
go func() {
for {
select {
case ev := <-watcher.Events:
log.Println("event:", ev)
reloadTemplates = true
case err := <-watcher.Errors:
log.Println("error:", err)
}
}
}()
err = watcher.Add(templateDir)
if err != nil {
fmt.Println(err)
}
}
func parseTemplates() {
t = template.New("templates")
var allFiles []string
files, err := ioutil.ReadDir(templateDir)
if err != nil {
fmt.Println("Error reading template dir")
}
for _, file := range files {
filename := file.Name()
if strings.HasSuffix(filename, ".html") {
allFiles = append(allFiles, templateDir+"/"+filename)
fmt.Println("Parsing", templateDir+"/"+filename)
}
}
if err != nil {
log.Fatal(err)
}
t = template.Must(template.ParseFiles(allFiles...))
}
func main() {
parseTemplates()
cwd = "./"
http.HandleFunc("/static/", assetsHandler)
for route, function := range routes {
http.HandleFunc(route, function)
}
log.Fatal(http.ListenAndServe(":8080", nil))
}
// AssetsHandler is a static file server that serves everything in
// static directory
func assetsHandler(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, staticDir+r.URL.Path)
}
// RootHandler handles the "/" connections
func rootHandler(w http.ResponseWriter, r *http.Request) {
if reloadTemplates {
parseTemplates()
reloadTemplates = false
}
err := t.ExecuteTemplate(w, "index", pages["index"])
if err != nil {
fmt.Println(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment