Use ThemesSlice instead of Themes in Header struct.
This commit is contained in:
parent
f54203d54f
commit
67ccca8b4e
|
@ -29,7 +29,8 @@ type Header struct {
|
||||||
Widgets PageWidgets
|
Widgets PageWidgets
|
||||||
Site *site
|
Site *site
|
||||||
Settings SettingMap
|
Settings SettingMap
|
||||||
Themes map[string]*Theme // TODO: Use a slice containing every theme instead of the main map for speed?
|
//Themes map[string]*Theme // TODO: Use a slice containing every theme instead of the main map for speed?
|
||||||
|
ThemesSlice []*Theme
|
||||||
Theme *Theme
|
Theme *Theme
|
||||||
//TemplateName string // TODO: Use this to move template calls to the router rather than duplicating them over and over and over?
|
//TemplateName string // TODO: Use this to move template calls to the router rather than duplicating them over and over and over?
|
||||||
CurrentUser *User // TODO: Deprecate CurrentUser on the page structs and use a pointer here
|
CurrentUser *User // TODO: Deprecate CurrentUser on the page structs and use a pointer here
|
||||||
|
|
|
@ -111,9 +111,10 @@ func cascadeForumPerms(fp *ForumPerms, u *User) {
|
||||||
func panelUserCheck(w http.ResponseWriter, r *http.Request, u *User) (h *Header, stats PanelStats, rerr RouteError) {
|
func panelUserCheck(w http.ResponseWriter, r *http.Request, u *User) (h *Header, stats PanelStats, rerr RouteError) {
|
||||||
theme := GetThemeByReq(r)
|
theme := GetThemeByReq(r)
|
||||||
h = &Header{
|
h = &Header{
|
||||||
Site: Site,
|
Site: Site,
|
||||||
Settings: SettingBox.Load().(SettingMap),
|
Settings: SettingBox.Load().(SettingMap),
|
||||||
Themes: Themes,
|
//Themes: Themes,
|
||||||
|
ThemesSlice: ThemesSlice,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
CurrentUser: u,
|
CurrentUser: u,
|
||||||
Hooks: GetHookTable(),
|
Hooks: GetHookTable(),
|
||||||
|
@ -165,8 +166,7 @@ func panelUserCheck(w http.ResponseWriter, r *http.Request, u *User) (h *Header,
|
||||||
// TODO: Optimise this by removing a superfluous string alloc
|
// TODO: Optimise this by removing a superfluous string alloc
|
||||||
var tname string
|
var tname string
|
||||||
if theme.OverridenMap != nil {
|
if theme.OverridenMap != nil {
|
||||||
_, ok := theme.OverridenMap[name]
|
if _, ok := theme.OverridenMap[name]; ok {
|
||||||
if ok {
|
|
||||||
tname = "_" + theme.Name
|
tname = "_" + theme.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,8 +193,8 @@ func simpleUserCheck(w http.ResponseWriter, r *http.Request, u *User) (lite *Hea
|
||||||
|
|
||||||
func GetThemeByReq(r *http.Request) *Theme {
|
func GetThemeByReq(r *http.Request) *Theme {
|
||||||
theme := &Theme{Name: ""}
|
theme := &Theme{Name: ""}
|
||||||
cookie, err := r.Cookie("current_theme")
|
cookie, e := r.Cookie("current_theme")
|
||||||
if err == nil {
|
if e == nil {
|
||||||
inTheme, ok := Themes[html.EscapeString(cookie.Value)]
|
inTheme, ok := Themes[html.EscapeString(cookie.Value)]
|
||||||
if ok && !theme.HideFromThemes {
|
if ok && !theme.HideFromThemes {
|
||||||
theme = inTheme
|
theme = inTheme
|
||||||
|
@ -216,9 +216,10 @@ func userCheck(w http.ResponseWriter, r *http.Request, u *User) (h *Header, rerr
|
||||||
func userCheck2(w http.ResponseWriter, r *http.Request, u *User, nano int64) (h *Header, rerr RouteError) {
|
func userCheck2(w http.ResponseWriter, r *http.Request, u *User, nano int64) (h *Header, rerr RouteError) {
|
||||||
theme := GetThemeByReq(r)
|
theme := GetThemeByReq(r)
|
||||||
h = &Header{
|
h = &Header{
|
||||||
Site: Site,
|
Site: Site,
|
||||||
Settings: SettingBox.Load().(SettingMap),
|
Settings: SettingBox.Load().(SettingMap),
|
||||||
Themes: Themes,
|
//Themes: Themes,
|
||||||
|
ThemesSlice: ThemesSlice,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
CurrentUser: u, // ! Some things rely on this being a pointer downstream from this function
|
CurrentUser: u, // ! Some things rely on this being a pointer downstream from this function
|
||||||
Hooks: GetHookTable(),
|
Hooks: GetHookTable(),
|
||||||
|
@ -282,16 +283,15 @@ func PrepResources(u *User, h *Header, theme *Theme) {
|
||||||
|
|
||||||
addPreScript := func(name string, i int) {
|
addPreScript := func(name string, i int) {
|
||||||
// TODO: Optimise this by removing a superfluous string alloc
|
// TODO: Optimise this by removing a superfluous string alloc
|
||||||
var tname string
|
|
||||||
if theme.OverridenMap != nil {
|
if theme.OverridenMap != nil {
|
||||||
//fmt.Printf("name %+v\n", name)
|
//fmt.Printf("name %+v\n", name)
|
||||||
//fmt.Printf("theme.OverridenMap %+v\n", theme.OverridenMap)
|
//fmt.Printf("theme.OverridenMap %+v\n", theme.OverridenMap)
|
||||||
if _, ok := theme.OverridenMap[name]; ok {
|
if _, ok := theme.OverridenMap[name]; ok {
|
||||||
tname = "_" + theme.Name
|
tname := "_" + theme.Name
|
||||||
|
//fmt.Printf("tname %+v\n", tname)
|
||||||
|
h.AddPreScriptAsync("tmpl_" + name + tname + ".js")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
//fmt.Printf("tname %+v\n", tname)
|
|
||||||
h.AddPreScriptAsync("tmpl_" + name + tname + ".js")
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
//fmt.Printf("tname %+v\n", tname)
|
//fmt.Printf("tname %+v\n", tname)
|
||||||
h.AddPreScriptAsync(ucstrs[i])
|
h.AddPreScriptAsync(ucstrs[i])
|
||||||
|
|
|
@ -24,6 +24,7 @@ type ThemeList map[string]*Theme
|
||||||
var Themes ThemeList = make(map[string]*Theme) // ? Refactor this into a store?
|
var Themes ThemeList = make(map[string]*Theme) // ? Refactor this into a store?
|
||||||
var DefaultThemeBox atomic.Value
|
var DefaultThemeBox atomic.Value
|
||||||
var ChangeDefaultThemeMutex sync.Mutex
|
var ChangeDefaultThemeMutex sync.Mutex
|
||||||
|
var ThemesSlice []*Theme
|
||||||
|
|
||||||
// TODO: Fallback to a random theme if this doesn't exist, so admins can remove themes they don't use
|
// TODO: Fallback to a random theme if this doesn't exist, so admins can remove themes they don't use
|
||||||
// TODO: Use this when the default theme doesn't exist
|
// TODO: Use this when the default theme doesn't exist
|
||||||
|
@ -41,12 +42,12 @@ var themeStmts ThemeStmts
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
DbInits.Add(func(acc *qgen.Accumulator) error {
|
DbInits.Add(func(acc *qgen.Accumulator) error {
|
||||||
t := "themes"
|
t, cols := "themes", "uname,default"
|
||||||
themeStmts = ThemeStmts{
|
themeStmts = ThemeStmts{
|
||||||
getAll: acc.Select(t).Columns("uname,default").Prepare(),
|
getAll: acc.Select(t).Columns(cols).Prepare(),
|
||||||
isDefault: acc.Select(t).Columns("default").Where("uname=?").Prepare(),
|
isDefault: acc.Select(t).Columns("default").Where("uname=?").Prepare(),
|
||||||
update: acc.Update(t).Set("default=?").Where("uname=?").Prepare(),
|
update: acc.Update(t).Set("default=?").Where("uname=?").Prepare(),
|
||||||
add: acc.Insert(t).Columns("uname,default").Fields("?,?").Prepare(),
|
add: acc.Insert(t).Columns(cols).Fields("?,?").Prepare(),
|
||||||
}
|
}
|
||||||
return acc.FirstError()
|
return acc.FirstError()
|
||||||
})
|
})
|
||||||
|
@ -76,43 +77,43 @@ func NewThemeList() (themes ThemeList, err error) {
|
||||||
return themes, err
|
return themes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
theme := &Theme{}
|
th := &Theme{}
|
||||||
err = json.Unmarshal(themeFile, theme)
|
err = json.Unmarshal(themeFile, th)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return themes, err
|
return themes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if theme.Name == "" {
|
if th.Name == "" {
|
||||||
return themes, errors.New("Theme " + themePath + " doesn't have a name set in theme.json")
|
return themes, errors.New("Theme " + themePath + " doesn't have a name set in theme.json")
|
||||||
}
|
}
|
||||||
if theme.Name == fallbackTheme {
|
if th.Name == fallbackTheme {
|
||||||
defaultTheme = fallbackTheme
|
defaultTheme = fallbackTheme
|
||||||
}
|
}
|
||||||
lastTheme = theme.Name
|
lastTheme = th.Name
|
||||||
|
|
||||||
// TODO: Implement the static file part of this and fsnotify
|
// TODO: Implement the static file part of this and fsnotify
|
||||||
if theme.Path != "" {
|
if th.Path != "" {
|
||||||
log.Print("Resolving redirect to " + theme.Path)
|
log.Print("Resolving redirect to " + th.Path)
|
||||||
themeFile, err := ioutil.ReadFile(theme.Path + "/theme.json")
|
themeFile, err := ioutil.ReadFile(th.Path + "/theme.json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return themes, err
|
return themes, err
|
||||||
}
|
}
|
||||||
theme = &Theme{Path: theme.Path}
|
th = &Theme{Path: th.Path}
|
||||||
err = json.Unmarshal(themeFile, theme)
|
err = json.Unmarshal(themeFile, th)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return themes, err
|
return themes, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
theme.Path = themePath
|
th.Path = themePath
|
||||||
}
|
}
|
||||||
|
|
||||||
theme.Active = false // Set this to false, just in case someone explicitly overrode this value in the JSON file
|
th.Active = false // Set this to false, just in case someone explicitly overrode this value in the JSON file
|
||||||
|
|
||||||
// TODO: Let the theme specify where it's resources are via the JSON file?
|
// TODO: Let the theme specify where it's resources are via the JSON file?
|
||||||
// TODO: Let the theme inherit CSS from another theme?
|
// TODO: Let the theme inherit CSS from another theme?
|
||||||
// ? - This might not be too helpful, as it only searches for /public/ and not if /public/ is empty. Still, it might help some people with a slightly less cryptic error
|
// ? - This might not be too helpful, as it only searches for /public/ and not if /public/ is empty. Still, it might help some people with a slightly less cryptic error
|
||||||
log.Print(theme.Path + "/public/")
|
log.Print(th.Path + "/public/")
|
||||||
_, err = os.Stat(theme.Path + "/public/")
|
_, err = os.Stat(th.Path + "/public/")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return themes, errors.New("We couldn't find this theme's resources. E.g. the /public/ folder.")
|
return themes, errors.New("We couldn't find this theme's resources. E.g. the /public/ folder.")
|
||||||
|
@ -122,31 +123,31 @@ func NewThemeList() (themes ThemeList, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if theme.FullImage != "" {
|
if th.FullImage != "" {
|
||||||
DebugLog("Adding theme image")
|
DebugLog("Adding theme image")
|
||||||
err = StaticFiles.Add(theme.Path+"/"+theme.FullImage, themePath)
|
err = StaticFiles.Add(th.Path+"/"+th.FullImage, themePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return themes, err
|
return themes, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
theme.TemplatesMap = make(map[string]string)
|
th.TemplatesMap = make(map[string]string)
|
||||||
theme.TmplPtr = make(map[string]interface{})
|
th.TmplPtr = make(map[string]interface{})
|
||||||
if theme.Templates != nil {
|
if th.Templates != nil {
|
||||||
for _, themeTmpl := range theme.Templates {
|
for _, themeTmpl := range th.Templates {
|
||||||
theme.TemplatesMap[themeTmpl.Name] = themeTmpl.Source
|
th.TemplatesMap[themeTmpl.Name] = themeTmpl.Source
|
||||||
theme.TmplPtr[themeTmpl.Name] = TmplPtrMap["o_"+themeTmpl.Source]
|
th.TmplPtr[themeTmpl.Name] = TmplPtrMap["o_"+themeTmpl.Source]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
theme.IntTmplHandle = DefaultTemplates
|
th.IntTmplHandle = DefaultTemplates
|
||||||
overrides, err := ioutil.ReadDir(theme.Path + "/overrides/")
|
overrides, err := ioutil.ReadDir(th.Path + "/overrides/")
|
||||||
if err != nil && !os.IsNotExist(err) {
|
if err != nil && !os.IsNotExist(err) {
|
||||||
return themes, err
|
return themes, err
|
||||||
}
|
}
|
||||||
if len(overrides) > 0 {
|
if len(overrides) > 0 {
|
||||||
overCount := 0
|
overCount := 0
|
||||||
theme.OverridenMap = make(map[string]bool)
|
th.OverridenMap = make(map[string]bool)
|
||||||
for _, override := range overrides {
|
for _, override := range overrides {
|
||||||
if override.IsDir() {
|
if override.IsDir() {
|
||||||
continue
|
continue
|
||||||
|
@ -159,25 +160,25 @@ func NewThemeList() (themes ThemeList, err error) {
|
||||||
}
|
}
|
||||||
overCount++
|
overCount++
|
||||||
nosuf := strings.TrimSuffix(override.Name(), ext)
|
nosuf := strings.TrimSuffix(override.Name(), ext)
|
||||||
theme.OverridenTemplates = append(theme.OverridenTemplates, nosuf)
|
th.OverridenTemplates = append(th.OverridenTemplates, nosuf)
|
||||||
theme.OverridenMap[nosuf] = true
|
th.OverridenMap[nosuf] = true
|
||||||
//theme.TmplPtr[nosuf] = TmplPtrMap["o_"+nosuf]
|
//th.TmplPtr[nosuf] = TmplPtrMap["o_"+nosuf]
|
||||||
log.Print("succeeded")
|
log.Print("succeeded")
|
||||||
}
|
}
|
||||||
|
|
||||||
localTmpls := template.New("")
|
localTmpls := template.New("")
|
||||||
err = loadTemplates(localTmpls, theme.Name)
|
err = loadTemplates(localTmpls, th.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return themes, err
|
return themes, err
|
||||||
}
|
}
|
||||||
theme.IntTmplHandle = localTmpls
|
th.IntTmplHandle = localTmpls
|
||||||
log.Printf("theme.OverridenTemplates: %+v\n", theme.OverridenTemplates)
|
log.Printf("theme.OverridenTemplates: %+v\n", th.OverridenTemplates)
|
||||||
log.Printf("theme.IntTmplHandle: %+v\n", theme.IntTmplHandle)
|
log.Printf("theme.IntTmplHandle: %+v\n", th.IntTmplHandle)
|
||||||
} else {
|
} else {
|
||||||
log.Print("no overrides for " + theme.Name)
|
log.Print("no overrides for " + th.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, res := range theme.Resources {
|
for i, res := range th.Resources {
|
||||||
ext := filepath.Ext(res.Name)
|
ext := filepath.Ext(res.Name)
|
||||||
switch ext {
|
switch ext {
|
||||||
case ".css":
|
case ".css":
|
||||||
|
@ -193,19 +194,19 @@ func NewThemeList() (themes ThemeList, err error) {
|
||||||
case "panel":
|
case "panel":
|
||||||
res.LocID = LocPanel
|
res.LocID = LocPanel
|
||||||
}
|
}
|
||||||
theme.Resources[i] = res
|
th.Resources[i] = res
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dock := range theme.Docks {
|
for _, dock := range th.Docks {
|
||||||
id, ok := DockToID[dock]
|
if id, ok := DockToID[dock]; ok {
|
||||||
if ok {
|
th.DocksID = append(th.DocksID, id)
|
||||||
theme.DocksID = append(theme.DocksID, id)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Bind the built template, or an interpreted one for any dock overrides this theme has
|
// TODO: Bind the built template, or an interpreted one for any dock overrides this theme has
|
||||||
|
|
||||||
themes[theme.Name] = theme
|
themes[th.Name] = th
|
||||||
|
ThemesSlice = append(ThemesSlice, th)
|
||||||
}
|
}
|
||||||
if defaultTheme == "" {
|
if defaultTheme == "" {
|
||||||
defaultTheme = lastTheme
|
defaultTheme = lastTheme
|
||||||
|
@ -221,18 +222,18 @@ func (t ThemeList) LoadActiveStatus() error {
|
||||||
ChangeDefaultThemeMutex.Lock()
|
ChangeDefaultThemeMutex.Lock()
|
||||||
defer ChangeDefaultThemeMutex.Unlock()
|
defer ChangeDefaultThemeMutex.Unlock()
|
||||||
|
|
||||||
rows, err := themeStmts.getAll.Query()
|
rows, e := themeStmts.getAll.Query()
|
||||||
if err != nil {
|
if e != nil {
|
||||||
return err
|
return e
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
var uname string
|
var uname string
|
||||||
var defaultThemeSwitch bool
|
var defaultThemeSwitch bool
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
err = rows.Scan(&uname, &defaultThemeSwitch)
|
e = rows.Scan(&uname, &defaultThemeSwitch)
|
||||||
if err != nil {
|
if e != nil {
|
||||||
return err
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// Was the theme deleted at some point?
|
// Was the theme deleted at some point?
|
||||||
|
@ -258,8 +259,8 @@ func (t ThemeList) LoadActiveStatus() error {
|
||||||
|
|
||||||
func (t ThemeList) LoadStaticFiles() error {
|
func (t ThemeList) LoadStaticFiles() error {
|
||||||
for _, theme := range t {
|
for _, theme := range t {
|
||||||
if err := theme.LoadStaticFiles(); err != nil {
|
if e := theme.LoadStaticFiles(); e != nil {
|
||||||
return err
|
return e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue