package main import ( "embed" "fmt" "html/template" "log" "net/http" "os" "path" "strings" "gopkg.in/yaml.v2" ) var ( //go:embed src data.yaml res embed.FS port string ) func init() { var ok bool if port, ok = os.LookupEnv("PORT"); !ok { port = "8080" } } func main() { dataBytes, err := res.ReadFile("data.yaml") if err != nil { panic(err) } var data map[string]interface{} if err := yaml.Unmarshal(dataBytes, &data); err != nil { panic(err) } for _, l := range data["social"].([]interface{}) { link := l.(map[interface{}]interface{}) if link["slug"] != "" { http.Handle(link["slug"].(string), http.RedirectHandler(link["url"].(string), http.StatusTemporaryRedirect)) } } funcMap := template.FuncMap(map[string]interface{}{ "join": func(objs []interface{}, key, joiner string) template.HTML { vals := []string{} for _, obj := range objs { val := obj.(map[interface{}]interface{})[key] vals = append(vals, val.(string)) } return template.HTML(strings.Join(vals, joiner)) }, "html": func(str string) template.HTML { return template.HTML(str) }, }) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { page := "src" + r.URL.Path if strings.HasSuffix(page, "/") { page = page + "index.html" } if strings.HasSuffix(page, ".html") || strings.HasSuffix(page, ".md") { tpl, err := template.New(path.Base(page)).Funcs(funcMap).ParseFS(res, page) if err != nil { log.Printf("page %s (%s) not found...", r.RequestURI, page) log.Println(err) w.WriteHeader(http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) if err := tpl.Execute(w, data); err != nil { log.Println(err) return } } else { // Serve up the best file format for image if strings.Contains(page, "headshot-transparent.png") { if strings.Contains(r.Header.Get("Accept"), "image/avif") { page = strings.Replace(page, ".png", ".avif", 1) } else if strings.Contains(r.Header.Get("Accept"), "image/webp") { page = strings.Replace(page, ".png", ".webp", 1) } } body, err := res.ReadFile(page) if err != nil { log.Printf("file %s (%s) not found...", r.RequestURI, page) w.WriteHeader(http.StatusInternalServerError) return } w.Write(body) return } }) // http.FileServer(http.FS(res)) fmt.Println("Server started at port " + port) log.Fatal(http.ListenAndServe(":"+port, nil)) }