Load all themes on startup
This is the first step to allow each user to have a different theme.
This commit is contained in:
parent
49167b9a28
commit
edf738f23d
1 changed files with 54 additions and 13 deletions
67
template.go
67
template.go
|
@ -4,17 +4,22 @@ import (
|
|||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
type tmpl struct {
|
||||
// TODO: add support for multiple themes
|
||||
t *template.Template
|
||||
const themesDir = "public/themes"
|
||||
|
||||
type renderer struct {
|
||||
base *template.Template
|
||||
themes map[string]*template.Template
|
||||
defaultTheme string
|
||||
}
|
||||
|
||||
func (t *tmpl) Render(w io.Writer, name string, data interface{}, ectx echo.Context) error {
|
||||
func (r *renderer) Render(w io.Writer, name string, data interface{}, ectx echo.Context) error {
|
||||
// ectx is the raw *echo.context, not our own *context
|
||||
ctx := ectx.Get("context").(*context)
|
||||
|
||||
|
@ -24,10 +29,29 @@ func (t *tmpl) Render(w io.Writer, name string, data interface{}, ectx echo.Cont
|
|||
}
|
||||
}
|
||||
|
||||
return t.t.ExecuteTemplate(w, name, data)
|
||||
// TODO: per-user theme selection
|
||||
t := r.base
|
||||
if r.defaultTheme != "" {
|
||||
t = r.themes[r.defaultTheme]
|
||||
}
|
||||
return t.ExecuteTemplate(w, name, data)
|
||||
}
|
||||
|
||||
func loadTemplates(logger echo.Logger, themeName string, plugins []Plugin) (*tmpl, error) {
|
||||
func loadTheme(name string, base *template.Template) (*template.Template, error) {
|
||||
theme, err := base.Clone()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
theme, err = theme.ParseGlob("public/themes/" + name + "/*.html")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return theme, nil
|
||||
}
|
||||
|
||||
func loadTemplates(logger echo.Logger, defaultTheme string, plugins []Plugin) (*renderer, error) {
|
||||
base := template.New("").Funcs(template.FuncMap{
|
||||
"tuple": func(values ...interface{}) []interface{} {
|
||||
return values
|
||||
|
@ -45,17 +69,34 @@ func loadTemplates(logger echo.Logger, themeName string, plugins []Plugin) (*tmp
|
|||
return nil, err
|
||||
}
|
||||
|
||||
theme, err := base.Clone()
|
||||
if err != nil {
|
||||
themes := make(map[string]*template.Template)
|
||||
|
||||
files, err := ioutil.ReadDir(themesDir)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if themeName != "" {
|
||||
logger.Printf("Loading theme \"%s\"", themeName)
|
||||
if _, err := theme.ParseGlob("public/themes/" + themeName + "/*.html"); err != nil {
|
||||
return nil, err
|
||||
for _, fi := range files {
|
||||
if !fi.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Printf("Loading theme '%v'", fi.Name())
|
||||
var err error
|
||||
if themes[fi.Name()], err = loadTheme(fi.Name(), base); err != nil {
|
||||
return nil, fmt.Errorf("failed to load theme '%v': %v", fi.Name(), err)
|
||||
}
|
||||
}
|
||||
|
||||
return &tmpl{theme}, err
|
||||
if defaultTheme != "" {
|
||||
if _, ok := themes[defaultTheme]; !ok {
|
||||
return nil, fmt.Errorf("failed to find default theme '%v'", defaultTheme)
|
||||
}
|
||||
}
|
||||
|
||||
return &renderer{
|
||||
base: base,
|
||||
themes: themes,
|
||||
defaultTheme: defaultTheme,
|
||||
}, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue