summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile14
-rw-r--r--go.mod3
-rw-r--r--htdocs/base.html29
-rw-r--r--htdocs/index.html3
-rw-r--r--htdocs/software/index.html7
-rw-r--r--htdocs/style.css29
-rw-r--r--index.html6
-rw-r--r--server.go106
8 files changed, 191 insertions, 6 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5add856
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+build: tidy format
+ go build
+
+serve: tidy format
+ go run .
+
+live:
+ rsync -rtvzP ./htdocs/ sam@samanthony.xyz:/var/www/htdocs/samanthony.xyz/
+
+format:
+ gofmt -s -w .
+
+tidy:
+ go mod tidy
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..ace7593
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module git.samanthony.xyz/samanthony.xyz
+
+go 1.18
diff --git a/htdocs/base.html b/htdocs/base.html
new file mode 100644
index 0000000..5c02174
--- /dev/null
+++ b/htdocs/base.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <!-- Child templates can choose to overwrite the default title -->
+ {{ define "title" }}<title>samanthony.xyz</title>{{ end }}
+ {{ template "title" }}
+
+ <!-- Child templates can apply their own styles -->
+ {{ define "style" }}{{ end }}
+ {{ template "style" }}
+ <link rel="stylesheet" href="/style.css">
+ </head>
+ <body>
+ <nav>
+ {{ $this_section := .Nav.ThisSection }}
+ {{ range .Nav.Links }}
+ {{ if eq .Href $this_section }}
+ <p>/</p><a class="this-section" href="{{ .Href }}">{{ .Label }}</a>
+ {{else }}
+ <p>|</p><a href="{{ .Href }}">{{ .Label }}</a>
+ {{ end }}
+ {{ end }}
+ <hr>
+ </nav>
+ {{ template "body_content" }}
+ </body>
+</html>
diff --git a/htdocs/index.html b/htdocs/index.html
new file mode 100644
index 0000000..ac2f7a6
--- /dev/null
+++ b/htdocs/index.html
@@ -0,0 +1,3 @@
+{{ define "body_content" }}
+ <p>Hello, world!</p>
+{{ end }}
diff --git a/htdocs/software/index.html b/htdocs/software/index.html
new file mode 100644
index 0000000..4b1092d
--- /dev/null
+++ b/htdocs/software/index.html
@@ -0,0 +1,7 @@
+{{ define "title" }}
+ <title>software | samanthony.xyz</title>
+{{ end }}
+
+{{ define "body_content" }}
+ <p>This is the software page</p>
+{{ end }}
diff --git a/htdocs/style.css b/htdocs/style.css
new file mode 100644
index 0000000..ae0ac35
--- /dev/null
+++ b/htdocs/style.css
@@ -0,0 +1,29 @@
+body {
+ margin-left: 0px;
+ margin-right: 0px;
+ margin-top: 0px;
+
+ background-color: black;
+ color: white;
+
+ font-family: sans-serif;
+}
+
+/* Navbar */
+nav {
+ background-color: #4acaa4;
+ font-size: 1.6em;
+}
+nav a {
+ font-size: 0.7em;
+ color: white;
+ text-decoration: none;
+}
+nav p:first-child + a { font-weight: bold; }
+nav a.this-section { font-style: italic; }
+nav p { display: inline; }
+nav p:first-child { margin-left: 0.1em; }
+nav hr {
+ margin: 0px;
+ color: white;
+}
diff --git a/index.html b/index.html
deleted file mode 100644
index 39a00d6..0000000
--- a/index.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!doctype html>
-<html>
- <body>
- <p>Hello, world!</p>
- </body>
-</html>
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))
+}