Something went wrong. Try again.
Lightweight and easily self-hostable Git forge.
Something went wrong. Try again.
2.7 kB · 131 lines
Go
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132package templating
import ( "farga/config" "farga/db/types" "farga/lib/mime" "html/template" "io/fs" "log" "maps" "net/http" "path/filepath" "strings"
"farga/lib"
"embed"
"github.com/gorilla/csrf")
//go:embed viewsvar templatesFS embed.FS
var FuncMap = template.FuncMap{ "GetMime": mime.Type, "IsImage": mime.IsImage, "IsVideo": mime.IsVideo, "IsText": mime.IsText, "Src": mime.Src, "Str": mime.ToStr, "RepoRoot": lib.RepoRoot, "SizeOf": lib.Size, "SizeLen": lib.SizeLen, "IsRangeable": lib.IsRangeable, "TruncateStr": lib.TruncateString, "SplitLines": lib.SplitLines,}
func findAndParseTemplates(fsys fs.FS, root string, funcMap template.FuncMap) (*template.Template, error) { rootTmpl := template.New("").Funcs(funcMap)
err := fs.WalkDir(fsys, root, func(path string, d fs.DirEntry, err error) error { if err != nil { return err }
if d.IsDir() || !strings.HasSuffix(path, ".html") { return nil }
b, err := fs.ReadFile(fsys, path) if err != nil { return err }
name := strings.TrimPrefix(path, root+"/")
_, err = rootTmpl.New(name).Parse(string(b)) return err })
if err != nil { return nil, err }
return rootTmpl, nil}
var templates *template.Template
func init() { var err error templates, err = findAndParseTemplates(templatesFS, ".", FuncMap) 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("templating", "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"] = config.C.Domain td["sshPort"] = config.C.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) }}