small pixel drawing of a pufferfish j3s.sh

main.go

package main

import (
	"html/template"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"git.j3s.sh/j3s.sh/feed"
)

// templateData is a mega-struct that gets
// passed to every single template - put whatever
// you want in it tbh.
//
// "data" is a global object that contains arbitrary
// data for use in templates. it's useful for it to be
// global since it may need to be available in arbitrary
// contexts. maybe that sucks. but idfk!
type templateData struct {
	FriendPosts []string
}

var data templateData

// the populate function populates the global "data" variable
// with ... data. with which to pass into templates.
func (t *templateData) populate() {
	t.FriendPosts = feed.FetchRecentFriendPosts()
}

func main() {
	data.populate()

	fs := http.FileServer(http.Dir("./static"))
	http.Handle("/static/", http.StripPrefix("/static/", fs))

	http.HandleFunc("/review/", babyHandler)
	http.HandleFunc("/idea/", babyHandler)
	http.HandleFunc("/", serveTemplate)

	log.Println("listening on :4666 tbh")
	err := http.ListenAndServe(":4666", nil)
	if err != nil {
		log.Fatal(err)
	}
}

func serveTemplate(w http.ResponseWriter, r *http.Request) {
	lp := filepath.Join("templates", "layout.html")
	if r.URL.Path == "/" {
		r.URL.Path = "index.html"
		// TODO: add some arbitrary refresh handler for fetchFriendPosts
	}
	fp := filepath.Join("templates", filepath.Clean(r.URL.Path))

	info, err := os.Stat(fp)
	if err != nil {
		if os.IsNotExist(err) {
			http.NotFound(w, r)
			return
		}
	}

	if info.IsDir() {
		http.NotFound(w, r)
		return
	}

	tmpl, err := template.ParseFiles(lp, fp)
	if err != nil {
		log.Println(err.Error())
		http.Error(w, http.StatusText(500), 500)
		return
	}

	err = tmpl.ExecuteTemplate(w, "layout", data)
	if err != nil {
		log.Println(err.Error())
		http.Error(w, http.StatusText(500), 500)
	}
}

func babyHandler(w http.ResponseWriter, r *http.Request) {
	lp := filepath.Join("templates", "simple-layout.html")
	fp := filepath.Join(strings.TrimPrefix(filepath.Clean(r.URL.Path), "/"))

	info, err := os.Stat(fp)
	if err != nil {
		if os.IsNotExist(err) {
			http.NotFound(w, r)
			return
		}
	}

	if info.IsDir() {
		http.NotFound(w, r)
		return
	}

	content, err := os.ReadFile(fp)
	if err != nil {
		log.Println(err.Error())
		http.Error(w, http.StatusText(500), 500)
		return
	}

	tmpl, err := template.ParseFiles(lp)
	if err != nil {
		log.Println(err.Error())
		http.Error(w, http.StatusText(500), 500)
		return
	}

	err = tmpl.ExecuteTemplate(w, "simple-layout", string(content))
	if err != nil {
		log.Println(err.Error())
		http.Error(w, http.StatusText(500), 500)
	}
}