/* * SPDX-FileCopyrightText: 2023 jordi fita mas * SPDX-License-Identifier: AGPL-3.0-only */ package template import ( "fmt" "html/template" "io" "net/http" "net/url" "path" "strconv" "strings" "dev.tandem.ws/tandem/camper/pkg/auth" httplib "dev.tandem.ws/tandem/camper/pkg/http" ) func adminTemplateFile(name string) string { return "web/templates/admin/" + name } func publicTemplateFile(name string) string { return "web/templates/public/" + name } func MustRenderAdmin(w io.Writer, r *http.Request, user *auth.User, company *auth.Company, filename string, data interface{}) { layout := "layout.gohtml" if httplib.IsHTMxRequest(r) { layout = "htmx.gohtml" } mustRenderLayout(w, user, company, adminTemplateFile, data, layout, filename) } func MustRenderAdminFiles(w io.Writer, r *http.Request, user *auth.User, company *auth.Company, data interface{}, filenames ...string) { layout := "layout.gohtml" if httplib.IsHTMxRequest(r) { layout = "htmx.gohtml" } filenames = append([]string{layout}, filenames...) mustRenderLayout(w, user, company, adminTemplateFile, data, filenames...) } func MustRenderNoLayout(w io.Writer, r *http.Request, user *auth.User, company *auth.Company, filename string, data interface{}) { mustRenderLayout(w, user, company, adminTemplateFile, data, filename) } func MustRenderPublic(w io.Writer, r *http.Request, user *auth.User, company *auth.Company, filename string, data interface{}) { layout := "layout.gohtml" mustRenderLayout(w, user, company, publicTemplateFile, data, layout, filename) } func MustRenderPublicFiles(w io.Writer, r *http.Request, user *auth.User, company *auth.Company, data interface{}, filenames ...string) { layout := "layout.gohtml" filenames = append([]string{layout}, filenames...) mustRenderLayout(w, user, company, publicTemplateFile, data, filenames...) } func mustRenderLayout(w io.Writer, user *auth.User, company *auth.Company, templateFile func(string) string, data interface{}, templates ...string) { t := template.New(templates[len(templates)-1]) t.Funcs(template.FuncMap{ "gettext": user.Locale.Get, "pgettext": user.Locale.GetC, "currentLocale": func() string { return user.Locale.Language.String() }, "isLoggedIn": func() bool { return user.LoggedIn }, "isAdmin": user.IsAdmin, "CSRFHeader": func() string { return fmt.Sprintf(`"%s": "%s"`, auth.CSRFTokenHeader, user.CSRFToken) }, "CSRFInput": func() template.HTML { return template.HTML(fmt.Sprintf(``, auth.CSRFTokenField, user.CSRFToken)) }, "raw": func(s string) template.HTML { return template.HTML(s) }, "replaceAll": func(s, old, new string) string { return strings.ReplaceAll(s, old, new) }, "humanizeBytes": func(bytes int64) string { return humanizeBytes(bytes) }, "queryEscape": func(s string) string { return url.QueryEscape(s) }, "inc": func(i int) int { return i + 1 }, "dec": func(i int) int { return i - 1 }, "hexToDec": func(s string) int { num, _ := strconv.ParseInt(s, 16, 0) return int(num) }, }) templates = append(templates, "form.gohtml") files := make([]string, len(templates)) for i, tmpl := range templates { if len(tmpl) > 4 && tmpl[0] == 'w' && tmpl[1] == 'e' && tmpl[2] == 'b' && tmpl[3] == '/' { files[i] = tmpl } else { files[i] = templateFile(tmpl) } } if _, err := t.ParseFiles(files...); err != nil { panic(err) } if rw, ok := w.(http.ResponseWriter); ok { rw.Header().Set("Content-Type", "text/html; charset=utf-8") } if err := t.ExecuteTemplate(w, path.Base(templates[0]), data); err != nil { panic(err) } }