feat: add handlers to serve template and styles

This commit is contained in:
Stevan Freeborn
2025-11-15 09:00:06 -06:00
parent b42c63532f
commit 03cbe49a30
10 changed files with 225 additions and 2 deletions
+52
View File
@@ -0,0 +1,52 @@
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"
[build]
args_bin = []
bin = "tmp\\main.exe"
cmd = "go build -o ./tmp/main.exe ./cmd/web/main.go"
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html", "css", "gohtml"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
post_cmd = []
pre_cmd = []
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false
[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"
[log]
main_only = false
silent = false
time = false
[misc]
clean_on_exit = false
[proxy]
app_port = 0
enabled = false
proxy_port = 0
[screen]
clear_on_rebuild = false
keep_scroll = true
+1
View File
@@ -11,4 +11,5 @@ profile.cov
go.work go.work
go.work.sum go.work.sum
.env .env
tmp/
+53 -2
View File
@@ -1,7 +1,58 @@
package main package main
import "fmt" import (
"context"
"errors"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/StevanFreeborn/links.stevanfreeborn.com/internal/handlers"
"github.com/StevanFreeborn/links.stevanfreeborn.com/internal/middleware"
)
func main() { func main() {
fmt.Println("Hello, World!") mux := http.NewServeMux()
mux.HandleFunc("/", handlers.Index)
mux.HandleFunc("/css/", handlers.CSS)
loggingMux := middleware.Logging(mux)
const addr = ":7777"
server := &http.Server{
Addr: addr,
Handler: loggingMux,
}
go func() {
fmt.Printf("Starting server on %s\n", addr)
err := server.ListenAndServe()
if !errors.Is(err, http.ErrServerClosed) {
log.Fatalf("HTTP server error: %v", err)
}
log.Println("Stopped serving new connections.")
}()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
<-sigChan
shutdownCtx, shutdownRelease := context.WithTimeout(context.Background(), 10*time.Second)
defer shutdownRelease()
if err := server.Shutdown(shutdownCtx); err != nil {
log.Fatalf("HTTP shutdown error: %v", err)
}
log.Println("Graceful shutdown complete.")
} }
+54
View File
@@ -0,0 +1,54 @@
/* CSS Resets */
* {
margin: 0;
padding: 0;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
button {
background: none;
border: none;
outline: none;
cursor: pointer;
}
a {
text-decoration: none;
color: inherit;
}
ul {
list-style-type: none;
}
img {
max-width: 100%;
display: block;
}
table {
width: 100%;
border-collapse: collapse;
}
/* Site Styles */
:root {
font-size: 16px;
}
html,
body {
height: 100%;
}
+13
View File
@@ -0,0 +1,13 @@
// Package assets contains embedded static assets for the application.
package assets
import (
"embed"
)
var (
//go:embed "templates/*"
Templates embed.FS
//go:embed "css/*"
CSS embed.FS
)
+12
View File
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Stevan's Links</title>
<link href="css/style.css" rel="stylesheet">
</head>
<body>
<h1 class="red">Stevan's Links</h1>
</body>
</html>
+24
View File
@@ -0,0 +1,24 @@
// Package handlers provides HTTP handlers for the web application.
package handlers
import (
"net/http"
"text/template"
"github.com/StevanFreeborn/links.stevanfreeborn.com/internal/assets"
)
func Index(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFS(assets.Templates, "templates/index.gohtml")
if err != nil {
http.Error(w, "Unable to load template", http.StatusInternalServerError)
return
}
t.Execute(w, nil)
}
func CSS(w http.ResponseWriter, r *http.Request) {
http.ServeFileFS(w, r, assets.CSS, r.URL.Path)
}
+16
View File
@@ -0,0 +1,16 @@
// Package middleware provides HTTP middleware for the web application.
package middleware
import (
"log"
"net/http"
"time"
)
func Logging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
log.Printf("%s %s %s", r.Method, r.RequestURI, time.Since(start))
})
}
View File
View File