render.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package template
  2. import (
  3. "io"
  4. "log"
  5. "net/http"
  6. "reflect"
  7. "strings"
  8. "codeberg.org/vnpower/pixivfe/v2/request_context"
  9. "codeberg.org/vnpower/pixivfe/v2/session"
  10. "codeberg.org/vnpower/pixivfe/v2/utils"
  11. "github.com/CloudyKit/jet/v6"
  12. )
  13. // global variable, yes.
  14. var views *jet.Set
  15. func Init(DisableCache bool) {
  16. if DisableCache {
  17. views = jet.NewSet(
  18. jet.NewOSFileSystemLoader("assets/views"),
  19. jet.InDevelopmentMode(), // disable cache
  20. )
  21. } else {
  22. views = jet.NewSet(
  23. jet.NewOSFileSystemLoader("assets/views"),
  24. )
  25. }
  26. for fn_name, fn := range GetTemplateFunctions() {
  27. views.AddGlobal(fn_name, fn)
  28. }
  29. }
  30. // render the template selected based on the name of type `T`
  31. func Render[T any](w http.ResponseWriter, r *http.Request, data T) error {
  32. w.Header().Set("content-type", "text/html; charset=utf-8")
  33. // todo: think about caching a bit more. see doc/dev/features/caching.md
  34. // w.Header().Set("expires", time.Now().Add(config.ExpiresIn).Format(time.RFC1123))
  35. w.WriteHeader(request_context.Get(r).RenderStatusCode)
  36. return RenderInner(w, GetTemplatingVariables(r), data)
  37. }
  38. func RenderInner[T any](w io.Writer, variables jet.VarMap, data T) error {
  39. template_name, found := strings.CutPrefix(reflect.TypeFor[T]().Name(), "Data_")
  40. if !found {
  41. log.Panicf("struct name does not start with 'Data_': %s", template_name)
  42. }
  43. template, err := views.GetTemplate(template_name + ".jet.html")
  44. if err != nil {
  45. return err
  46. }
  47. views.Parse(template_name+".jet.html", template.String())
  48. return template.Execute(w, variables, data)
  49. }
  50. func GetTemplatingVariables(r *http.Request) jet.VarMap {
  51. // Pass in values that we want to be available to all pages here
  52. token := session.GetPixivToken(r)
  53. baseURL := utils.Origin(r)
  54. pageURL := r.URL.String()
  55. cookies := map[string]string{}
  56. for _, name := range session.AllCookieNames {
  57. value := session.GetCookie(r, name)
  58. cookies[string(name)] = value
  59. }
  60. return jet.VarMap{}.
  61. Set("BaseURL", baseURL).
  62. Set("PageURL", pageURL).
  63. Set("LoggedIn", token != "").
  64. Set("Queries", r.URL.Query().Encode()).
  65. Set("CookieList", cookies)
  66. }