summaryrefslogtreecommitdiffstats
path: root/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'server.go')
-rw-r--r--server.go106
1 files changed, 106 insertions, 0 deletions
diff --git a/server.go b/server.go
new file mode 100644
index 0000000..d40c86c
--- /dev/null
+++ b/server.go
@@ -0,0 +1,106 @@
+package main
+
+import (
+ "fmt"
+ tmpl "html/template"
+ "io/fs"
+ "log"
+ "net/http"
+ "os"
+ "path"
+ fp "path/filepath"
+ "strings"
+)
+
+const (
+ host = ""
+ port = "6969"
+ root = "htdocs/"
+)
+
+var tmpls = make(map[string]*tmpl.Template)
+
+func init() {
+ err := fp.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
+ if fp.Clean(path) == fp.Clean(root) ||
+ fp.Ext(path) != ".html" ||
+ path == fp.Join(root, "base.html") {
+ return nil
+ }
+ label := path[len(fp.Clean(root)):]
+ tmpls[label] = tmpl.Must(tmpl.ParseFiles(fp.Join(root, "base.html"), path))
+ return nil
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+}
+
+type Page struct {
+ Nav Nav
+}
+
+type Nav struct {
+ ThisSection string
+ Links []NavLink
+}
+
+type NavLink struct {
+ Href string
+ Label string
+}
+
+var nav = Nav{
+ Links: []NavLink{
+ {"/", "samanthony.xyz"},
+ {"/software/", "software"},
+ },
+}
+
+func rootHandler(w http.ResponseWriter, r *http.Request) {
+ reqPath := r.URL.Path
+
+ // If request directory, serve index.html.
+ // ie. /software -> /software/index.html
+ if info, err := os.Stat(fp.Join(root, reqPath)); err == nil {
+ if info.IsDir() {
+ reqPath = path.Join(reqPath, "index.html")
+ }
+ } else if os.IsNotExist(err) {
+ http.NotFound(w, r)
+ return
+ } else {
+ fmt.Println(err)
+ code := http.StatusInternalServerError
+ http.Error(w, http.StatusText(code), code)
+ return
+ }
+
+ if t, ok := tmpls[reqPath]; ok {
+ thisSection := ""
+ for _, link := range nav.Links {
+ if strings.HasPrefix(reqPath, link.Href) {
+ thisSection = link.Href
+ }
+ }
+ nav := nav
+ nav.ThisSection = thisSection
+ page := Page{nav}
+
+ err := t.Execute(w, page)
+ if err != nil {
+ fmt.Println(err)
+ code := http.StatusInternalServerError
+ http.Error(w, http.StatusText(code), code)
+ return
+ }
+ } else {
+ http.ServeFile(w, r, fp.Join(root, reqPath))
+ }
+}
+
+func main() {
+ http.HandleFunc("/", rootHandler)
+ fmt.Printf("Listening on %s:%s\n", host, port)
+ log.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%s", host, port), nil))
+}