mirror of
https://codeberg.org/VnPower/PixivFE
synced 2024-12-06 19:16:23 +01:00
109 lines
2.4 KiB
Go
109 lines
2.4 KiB
Go
package template
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"encoding/binary"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"reflect"
|
|
"strings"
|
|
|
|
"github.com/zeebo/xxh3"
|
|
|
|
"codeberg.org/vnpower/pixivfe/v2/server/session"
|
|
"codeberg.org/vnpower/pixivfe/v2/server/utils"
|
|
|
|
"github.com/CloudyKit/jet/v6"
|
|
)
|
|
|
|
// global variable, yes.
|
|
var views *jet.Set
|
|
|
|
func Init(DisableCache bool, assetsLocation string) {
|
|
if DisableCache {
|
|
views = jet.NewSet(
|
|
NewLocalizedFSLoader(assetsLocation),
|
|
jet.InDevelopmentMode(), // disable cache
|
|
)
|
|
} else {
|
|
views = jet.NewSet(
|
|
NewLocalizedFSLoader(assetsLocation),
|
|
)
|
|
}
|
|
for fn_name, fn := range GetTemplateFunctions() {
|
|
views.AddGlobal(fn_name, fn)
|
|
}
|
|
}
|
|
|
|
func Render[T any](w io.Writer, variables jet.VarMap, data T) (string, error) {
|
|
template_name, found := strings.CutPrefix(reflect.TypeFor[T]().Name(), "Data_")
|
|
if !found {
|
|
log.Panicf("struct name does not start with 'Data_': %s", template_name)
|
|
}
|
|
|
|
template, err := views.GetTemplate(template_name + ".jet.html")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
views.Parse(template_name+".jet.html", template.String())
|
|
|
|
// Create buffer to capture rendered output
|
|
buf := &bytes.Buffer{}
|
|
|
|
// Execute template to buffer
|
|
if err := template.Execute(buf, variables, data); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// Generate ETag
|
|
hash := xxh3.Hash(buf.Bytes())
|
|
hash_bytes := make([]byte, 8)
|
|
binary.LittleEndian.PutUint64(hash_bytes, uint64(hash))
|
|
etag := template_name + ":" + base64.RawURLEncoding.EncodeToString(hash_bytes)
|
|
|
|
// Write buffer to original writer
|
|
if _, err := io.Copy(w, buf); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return etag, nil
|
|
}
|
|
|
|
func GetTemplatingVariables(r *http.Request) jet.VarMap {
|
|
// Pass in values that we want to be available to all pages here
|
|
token := session.GetUserToken(r)
|
|
baseURL := utils.Origin(r)
|
|
currentPath := r.URL.String()
|
|
|
|
cookies := map[string]string{}
|
|
cookies_ordered := []struct {
|
|
k string
|
|
v string
|
|
}{}
|
|
for _, name := range session.AllCookieNames {
|
|
value := session.GetCookie(r, name)
|
|
cookies[string(name)] = value
|
|
cookies_ordered = append(cookies_ordered, struct {
|
|
k string
|
|
v string
|
|
}{string(name), value})
|
|
}
|
|
|
|
queries := make(map[string]string)
|
|
|
|
for k, v := range r.URL.Query() {
|
|
queries[k] = v[0]
|
|
}
|
|
|
|
return jet.VarMap{}.
|
|
Set("BaseURL", baseURL).
|
|
Set("CurrentPath", currentPath).
|
|
Set("LoggedIn", token != "").
|
|
Set("Queries", queries).
|
|
Set("CookieList", cookies).
|
|
Set("CookieListOrdered", cookies_ordered)
|
|
}
|