Something went wrong. Try again.
Lightweight and easily self-hostable Git forge.
Something went wrong. Try again.
2.7 kB · 125 lines
Go
at bugfixes
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126package templating
import ( "farga/db/types" "farga/lib/mime" "html/template" "log" "maps" "net/http" "os" "path/filepath" "strings"
"farga/lib"
"github.com/gorilla/csrf")
var FuncMap = template.FuncMap{ "GetMime": mime.MimeType, "IsImage": mime.IsImage, "IsText": mime.IsText, "Src": mime.Src, "Str": mime.ToStr, "RepoRoot": lib.RepoRoot, "SizeOf": lib.Size, "IsRangeable": lib.IsRangeable, "TruncateStr": lib.TruncateString,}
// Source: https://stackoverflow.com/a/50581032 (with modifications) | License: CC BY-SA 4.0func findAndParseTemplates(rootDir string, funcMap template.FuncMap) (*template.Template, error) { cleanRoot := filepath.Clean(rootDir) pfx := len(cleanRoot) + 1 root := template.Must(template.New("").Funcs(FuncMap), nil)
err := filepath.Walk(cleanRoot, func(path string, info os.FileInfo, e1 error) error { if !info.IsDir() && strings.HasSuffix(path, ".html") { if e1 != nil { return e1 }
b, e2 := os.ReadFile(path) if e2 != nil { return e2 }
name := path[pfx:] t := root.New(name).Funcs(funcMap) _, e2 = t.Parse(string(b)) if e2 != nil { return e2 } }
return nil })
return root, err}
// end of snippet? lol
var templates *template.Template
func init() { var err error templates, err = findAndParseTemplates("views/", nil) if err != nil { log.Fatal(err) }}
// Renders a template inside a given layout. You can also pass it any data.func Render(w http.ResponseWriter, r *http.Request, layout, page string, data ...any) { var td = make(map[string]any) if len(data) > 0 { if m, ok := data[0].(map[string]any); ok { maps.Copy(td, m) } else { // if data was something else, store it under "data" td["data"] = data[0] } }
tmpl, err := templates.Clone() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return }
tmpl, err = tmpl.ParseFiles(filepath.Join("views", page+".html")) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return }
if v := r.Context().Value(lib.ErrorKey); v != nil { td["error"] = v }
if v := r.Context().Value(lib.MessageKey); v != nil { if s, ok := v.(string); ok && s != "" { td["message"] = s } }
user, ok := r.Context().Value(lib.UserKey).(*types.User) if ok { td["user"] = user td["loggedIn"] = true } else { td["loggedIn"] = false // no user = not logged in. }
td["sshDomain"] = lib.SSHDomain td["sshPort"] = lib.SSHPort
td["csrfField"] = csrf.TemplateField(r) // append {{ .csrfField }} to every form.
err = tmpl.ExecuteTemplate(w, layout, td) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) }}