a love letter to tangled (android, iOS, and a search API)
at main 97 lines 2.9 kB view raw
1package view 2 3import ( 4 "embed" 5 "html/template" 6 "io/fs" 7 "net/http" 8) 9 10//go:embed templates static api-docs.json 11var content embed.FS 12 13var pageTemplates map[string]*template.Template 14 15func init() { 16 pageTemplates = make(map[string]*template.Template) 17 18 for _, name := range []string{ 19 "index.html", 20 } { 21 pageTemplates[name] = template.Must(template.New("layout").ParseFS(content, 22 "templates/layout.html", 23 "templates/"+name, 24 )) 25 } 26 27 for _, name := range []string{ 28 "docs/index.html", 29 "docs/search.html", 30 "docs/documents.html", 31 "docs/health.html", 32 "docs/actors.html", 33 "docs/issues.html", 34 "docs/pulls.html", 35 "docs/identity.html", 36 "docs/activity.html", 37 "docs/profiles.html", 38 "docs/xrpc.html", 39 } { 40 pageTemplates[name] = template.Must(template.New("layout").ParseFS(content, 41 "templates/layout.html", 42 "templates/partials/doc-entry.html", 43 "templates/"+name, 44 )) 45 } 46} 47 48// Handler returns an http.Handler that serves the site pages and static assets. 49func Handler() http.Handler { 50 mux := http.NewServeMux() 51 52 staticFS, _ := fs.Sub(content, "static") 53 mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServerFS(staticFS))) 54 55 mux.HandleFunc("GET /docs/search", renderDocPage("docs/search.html", "search")) 56 mux.HandleFunc("GET /docs/documents", renderDocPage("docs/documents.html", "documents")) 57 mux.HandleFunc("GET /docs/health", renderDocPage("docs/health.html", "health")) 58 mux.HandleFunc("GET /docs/actors", renderDocPage("docs/actors.html", "actors")) 59 mux.HandleFunc("GET /docs/issues", renderDocPage("docs/issues.html", "issues")) 60 mux.HandleFunc("GET /docs/pulls", renderDocPage("docs/pulls.html", "pulls")) 61 mux.HandleFunc("GET /docs/identity", renderDocPage("docs/identity.html", "identity")) 62 mux.HandleFunc("GET /docs/activity", renderDocPage("docs/activity.html", "activity")) 63 mux.HandleFunc("GET /docs/profiles", renderDocPage("docs/profiles.html", "profiles")) 64 mux.HandleFunc("GET /docs/xrpc", renderDocPage("docs/xrpc.html", "proxy")) 65 mux.HandleFunc("GET /docs", renderPage("docs/index.html")) 66 mux.HandleFunc("GET /{$}", renderPage("index.html")) 67 68 return mux 69} 70 71func renderPage(name string) http.HandlerFunc { 72 return func(w http.ResponseWriter, r *http.Request) { 73 tmpl, ok := pageTemplates[name] 74 if !ok { 75 http.NotFound(w, r) 76 return 77 } 78 w.Header().Set("Content-Type", "text/html; charset=utf-8") 79 if err := tmpl.ExecuteTemplate(w, "layout", nil); err != nil { 80 http.Error(w, "template error", http.StatusInternalServerError) 81 } 82 } 83} 84 85func renderDocPage(name, page string) http.HandlerFunc { 86 return func(w http.ResponseWriter, r *http.Request) { 87 tmpl, ok := pageTemplates[name] 88 if !ok { 89 http.NotFound(w, r) 90 return 91 } 92 w.Header().Set("Content-Type", "text/html; charset=utf-8") 93 if err := tmpl.ExecuteTemplate(w, "layout", PageDocs(page)); err != nil { 94 http.Error(w, "template error", http.StatusInternalServerError) 95 } 96 } 97}