dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

templates.go (5158B)


      1 package template
      2 
      3 import (
      4 	"dkforest/pkg/global"
      5 	"dkforest/pkg/web/clientFrontends"
      6 	hutils "dkforest/pkg/web/handlers/utils"
      7 	"fmt"
      8 	"html/template"
      9 	"io"
     10 	"path/filepath"
     11 	"strings"
     12 	"time"
     13 
     14 	"dkforest/bindata"
     15 	"dkforest/pkg/config"
     16 	"dkforest/pkg/database"
     17 	"dkforest/pkg/utils"
     18 	"github.com/labstack/echo"
     19 	"github.com/nicksnyder/go-i18n/v2/i18n"
     20 )
     21 
     22 // Templates ...
     23 type Templates struct {
     24 	Templates map[string]*template.Template
     25 	funcMap   FuncMap
     26 	e         *echo.Echo
     27 }
     28 
     29 // NewTemplateBuilder ...
     30 func NewTemplateBuilder(e *echo.Echo) *Templates {
     31 	t := new(Templates)
     32 	t.funcMap = make(FuncMap)
     33 	t.e = e
     34 	return t
     35 }
     36 
     37 // AddFn ...
     38 func (t *Templates) AddFn(name string, fn any) {
     39 	t.funcMap[name] = fn
     40 }
     41 
     42 type templateDataStruct struct {
     43 	Bundle          *i18n.Bundle
     44 	AcceptLanguage  string
     45 	Lang            string
     46 	Data            any
     47 	VERSION         string
     48 	SHA             string
     49 	VersionHTML     template.HTML
     50 	ShaHTML         template.HTML
     51 	LogoASCII       template.HTML
     52 	NullUsername    string
     53 	DB              *database.DkfDB
     54 	CSRF            string
     55 	Master          bool
     56 	Development     bool
     57 	BaseKeywords    string
     58 	TmplName        string
     59 	AuthUser        *database.User
     60 	InboxCount      int64
     61 	WallpaperImg    string
     62 	IsAprilFool2023 bool
     63 	GitURL          string
     64 	Reverse         func(string, ...any) string
     65 }
     66 
     67 // Render render a template
     68 func (t *Templates) Render(w io.Writer, name string, data any, c echo.Context) error {
     69 	tmpl := t.Templates[name]
     70 
     71 	db := c.Get("database").(*database.DkfDB)
     72 	clientFE := c.Get("clientFE").(clientFrontends.ClientFrontend)
     73 
     74 	d := templateDataStruct{}
     75 	d.TmplName = name
     76 	d.Data = data
     77 	d.VERSION = config.Global.AppVersion.Get().Original()
     78 	if config.Development.IsTrue() {
     79 		d.VERSION += utils.FormatInt64(time.Now().Unix())
     80 	}
     81 	d.Reverse = c.Echo().Reverse // {{ call .Reverse "name" }} || {{ call .Reverse "name" "params" }}
     82 	d.Bundle = c.Get("bundle").(*i18n.Bundle)
     83 	//d.SHA = config.Global.Sha()
     84 	d.VersionHTML = template.HTML(fmt.Sprintf("<!-- VERSION: %s -->", config.Global.AppVersion.Get().Original()))
     85 	d.ShaHTML = template.HTML(fmt.Sprintf("<!-- SHA: %s -->", config.Global.Sha.Get()))
     86 	d.NullUsername = config.NullUsername
     87 	d.CSRF, _ = c.Get("csrf").(string)
     88 	d.DB = db
     89 	d.AcceptLanguage = c.Get("accept-language").(string)
     90 	d.Lang = c.Get("lang").(string)
     91 	d.BaseKeywords = strings.Join(getBaseKeywords(), ", ")
     92 	d.Development = config.Development.Load()
     93 	d.AuthUser = c.Get("authUser").(*database.User)
     94 	switch clientFE {
     95 	case clientFrontends.TorClientFE:
     96 		d.GitURL = config.DkfGitOnion
     97 	case clientFrontends.I2PClientFE:
     98 		d.GitURL = config.I2pGitOnion
     99 	}
    100 
    101 	d.WallpaperImg = "/public/img/login_bg.jpg"
    102 	year, month, day := time.Now().UTC().Date()
    103 	d.IsAprilFool2023 = year == 2023 && month == time.April && day == 1
    104 	if strings.HasPrefix(c.QueryParam("redirect"), "/poker") {
    105 		d.WallpaperImg = "/public/img/login_bg_poker.jpg"
    106 	} else if month == time.October {
    107 		d.WallpaperImg = "/public/img/halloween_bg.jpg"
    108 	} else if month == time.December {
    109 		d.WallpaperImg = "/public/img/xmas.jpg"
    110 	} else if month == time.January {
    111 		d.WallpaperImg = "/public/img/login_bg_1.jpg"
    112 	} else if d.IsAprilFool2023 {
    113 		d.WallpaperImg = "/public/img/login_bg_2.jpg"
    114 	}
    115 
    116 	if d.AuthUser != nil {
    117 		var sessionToken string
    118 		if authCookie, err := c.Cookie(hutils.AuthCookieName); err == nil {
    119 			sessionToken = authCookie.Value
    120 		}
    121 		d.InboxCount = global.GetUserNotificationCount(db, d.AuthUser.ID, sessionToken)
    122 	}
    123 
    124 	return tmpl.ExecuteTemplate(w, "base", d)
    125 }
    126 
    127 // Keywords use for html meta tag, for SEO
    128 func getBaseKeywords() []string {
    129 	return []string{}
    130 }
    131 
    132 // BuildTemplates build all templates
    133 func (t *Templates) BuildTemplates() {
    134 	t.Templates = make(map[string]*template.Template)
    135 
    136 	bases := []string{
    137 		"views/pages/captcha-tmpl.gohtml",
    138 		"views/pages/pagination.gohtml",
    139 		"views/pages/anti-prefill.gohtml"}
    140 	buildTemplatesHelper("views/pages", t.Templates, "", bases, t.funcMap)
    141 }
    142 
    143 func buildTemplatesHelper(root string, tmpls map[string]*template.Template, prefix string, bases []string, fnsMap FuncMap) {
    144 	if _, err := bindata.AssetInfo(root + prefix + "/index.gohtml"); err == nil {
    145 		bases = append(bases, root+prefix+"/index.gohtml")
    146 	}
    147 	viewsPages, _ := bindata.AssetDir(root + prefix)
    148 	for _, page := range viewsPages {
    149 		// Recursively process folders
    150 		ext := filepath.Ext(page)
    151 		if !strings.HasSuffix(page, ".gohtml") {
    152 			buildTemplatesHelper(root, tmpls, prefix+"/"+page, bases, fnsMap)
    153 			continue
    154 		}
    155 		// Create template
    156 		page = strings.TrimSuffix(page, ".gohtml")
    157 		tmpl := New("_", bindata.Asset).Funcs(fnsMap)
    158 		parseBases(tmpl, bases)
    159 		tmpl = Must(tmpl.Parse(root + prefix + "/" + page + ext))
    160 		// Add to templates collection
    161 		tmplName := buildTemplateName(prefix, page)
    162 		tmpls[tmplName] = tmpl.Tmpl
    163 	}
    164 }
    165 
    166 func buildTemplateName(prefix, page string) string {
    167 	tmplName := strings.TrimPrefix(prefix, "/")
    168 	tmplName = strings.Join(strings.Split(tmplName, "/"), ".") + "." + page
    169 	tmplName = strings.TrimPrefix(tmplName, ".")
    170 	return tmplName
    171 }
    172 
    173 func parseBases(tmpl *Template, bases []string) {
    174 	for _, b := range bases {
    175 		tmpl = Must(tmpl.Parse(b))
    176 	}
    177 }