diff --git a/common/template_init.go b/common/template_init.go index 3d5c3076..d6c11f15 100644 --- a/common/template_init.go +++ b/common/template_init.go @@ -162,11 +162,11 @@ func CompileTemplates() error { log.Print("Compiling the templates") // TODO: Implement per-theme template overrides here too overriden := make(map[string]map[string]bool) - for _, theme := range Themes { - overriden[theme.Name] = make(map[string]bool) - log.Printf("theme.OverridenTemplates: %+v\n", theme.OverridenTemplates) - for _, override := range theme.OverridenTemplates { - overriden[theme.Name][override] = true + for _, th := range Themes { + overriden[th.Name] = make(map[string]bool) + log.Printf("th.OverridenTemplates: %+v\n", th.OverridenTemplates) + for _, override := range th.OverridenTemplates { + overriden[th.Name][override] = true } } log.Printf("overriden: %+v\n", overriden) @@ -175,6 +175,7 @@ func CompileTemplates() error { Minify: Config.MinifyTemplates, Debug: Dev.DebugMode, SuperDebug: Dev.TemplateDebug, + DockToID: DockToID, } c := tmpl.NewCTemplateSet("normal") c.SetConfig(config) @@ -195,13 +196,13 @@ func CompileTemplates() error { log.Printf("oroots: %+v\n", oroots) log.Print("Compiling the per-theme templates") - for theme, tmpls := range oroots { - c.ResetLogs("normal-" + theme) - c.SetThemeName(theme) + for th, tmpls := range oroots { + c.ResetLogs("normal-" + th) + c.SetThemeName(th) c.SetPerThemeTmpls(tmpls) - log.Print("theme: ", theme) + log.Print("th: ", th) log.Printf("perThemeTmpls: %+v\n", tmpls) - err := compileTemplates(&wg, c, theme) + err := compileTemplates(&wg, c, th) if err != nil { return err } @@ -229,6 +230,7 @@ func compileCommons(c *tmpl.CTemplateSet, head, head2 *Header, forumList []Forum topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 1, 0, "classname", 0, "", user2, "", 0, user3, "General", "/forum/general.2", nil}) topicListPage := TopicListPage{htitle("Topic List"), topicsList, forumList, Config.DefaultForum, TopicListSort{"lastupdated", false}, Paginator{[]int{1}, 1, 1}} o.Add("topics", "c.TopicListPage", topicListPage) + o.Add("topics_mini", "c.TopicListPage", topicListPage) forumItem := BlankForum(1, "general-forum.1", "General Forum", "Where the general stuff happens", true, "all", 0, "", 0) forumPage := ForumPage{htitle("General Forum"), topicsList, forumItem, Paginator{[]int{1}, 1, 1}} @@ -472,6 +474,7 @@ func CompileJSTemplates() error { SkipTmplPtrMap: true, SkipInitBlock: false, PackageName: "tmpl", + DockToID: DockToID, } c := tmpl.NewCTemplateSet("js") c.SetConfig(config) diff --git a/common/templates/templates.go b/common/templates/templates.go index c4d56cb7..9e1903a9 100644 --- a/common/templates/templates.go +++ b/common/templates/templates.go @@ -42,6 +42,7 @@ type CTemplateConfig struct { SkipTmplPtrMap bool SkipInitBlock bool PackageName string + DockToID map[string]int } // nolint @@ -249,7 +250,7 @@ func Tmpl_` + fname + `(tmpl_i interface{}, w io.Writer) error { c.fileDir = fileDir content, err := c.loadTemplate(c.fileDir, name) if err != nil { - c.detail("bailing out: ", err) + c.detail("bailing out:", err) return "", "", "", err } @@ -274,7 +275,7 @@ func (c *CTemplateSet) Compile(name, fileDir, expects string, expectsInt interfa c.fileDir = fileDir content, err := c.loadTemplate(c.fileDir, name) if err != nil { - c.detail("bailing out: ", err) + c.detail("bailing out:", err) return "", err } @@ -455,7 +456,7 @@ func (c *CTemplateSet) compile(name, content, expects string, expectsInt interfa if len(c.langIndexToName) > 0 { for i, name := range c.langIndexToName { //l += `"` + name + `"` + ",\n" - if i == 0{ + if i == 0 { l += `"` + name + `"` } else { l += `,"` + name + `"` @@ -541,7 +542,8 @@ if !ok { for fid := 0; len(outBuf) > fid; fid++ { fr := outBuf[fid] c.detail(fr.Type + " frame") - if fr.Type == "text" { + switch { + case fr.Type == "text": c.detail(fr) oid := fid c.detail("oid:", oid) @@ -568,14 +570,13 @@ if !ok { c.detail("post fid:", fid) } writeTextFrame(fr.TemplateName, fr.Extra.(int)-skip) - } else if fr.Type == "varsub" || fr.Type == "cvarsub" { + case fr.Type == "varsub" || fr.Type == "cvarsub": fout += "w.Write(" + fr.Body + ")\n" - } else if fr.Type == "identifier" { - fout += fr.Body - } else if fr.Type == "lang" { + case fr.Type == "lang": //fout += "w.Write(plist[" + strconv.Itoa(fr.Extra.(int)) + "])\n" fout += "w.Write(" + fname + "_phrase_arr[" + strconv.Itoa(fr.Extra.(int)) + "])\n" - } else { + //case fr.Type == "identifier": + default: fout += fr.Body } } @@ -587,7 +588,7 @@ if !ok { } for _, frag := range c.fragBuf { - c.detail("frag: ", frag) + c.detail("frag:", frag) if frag.Seen { c.detail("invisible") continue @@ -745,7 +746,7 @@ func (c *CTemplateSet) addText(con CContext, text []byte) { return } nodeText := string(text) - c.detail("con.TemplateName: ", con.TemplateName) + c.detail("con.TemplateName:", con.TemplateName) fragIndex := c.fragmentCursor[con.TemplateName] _, ok := c.fragOnce[con.TemplateName] c.fragBuf = append(c.fragBuf, Fragment{nodeText, con.TemplateName, fragIndex, ok}) @@ -756,7 +757,7 @@ func (c *CTemplateSet) addText(con CContext, text []byte) { func (c *CTemplateSet) compileRangeNode(con CContext, node *parse.RangeNode) { c.dumpCall("compileRangeNode", con, node) defer c.retCall("compileRangeNode") - c.detail("node.Pipe: ", node.Pipe) + c.detail("node.Pipe:", node.Pipe) var expr string var outVal reflect.Value for _, cmd := range node.Pipe.Cmds { @@ -882,7 +883,7 @@ func (c *CTemplateSet) compileSubSwitch(con CContext, node *parse.CommandNode) { cur = c.skipStructPointers(cur, id) c.checkIfValid(cur, con.VarHolder, con.HoldReflect, varBit, multiline) - c.detail("in-loop varBit: " + varBit) + c.detail("in-loop varBit:" + varBit) if cur.Kind() == reflect.Map { cur = cur.MapIndex(reflect.ValueOf(id)) varBit += "[\"" + id + "\"]" @@ -927,7 +928,7 @@ func (c *CTemplateSet) compileSubSwitch(con CContext, node *parse.CommandNode) { } varBit += cur.Type().Name() + ")" } - c.detail("End Cycle: ", varBit) + c.detail("End Cycle:", varBit) } if multiline { @@ -1026,19 +1027,19 @@ func (c *CTemplateSet) compileIdentSwitchN(con CContext, n *parse.CommandNode) ( } func (c *CTemplateSet) dumpSymbol(pos int, node *parse.CommandNode, symbol string) { - c.detail("symbol: ", symbol) + c.detail("symbol:", symbol) c.detail("node.Args[pos+1]", node.Args[pos+1]) c.detail("node.Args[pos+2]", node.Args[pos+2]) } -func (c *CTemplateSet) compareFunc(con CContext, pos int, node *parse.CommandNode, compare string) (out string) { - c.dumpSymbol(pos, node, compare) - return c.compileIfVarSubN(con, node.Args[pos+1].String()) + " " + compare + " " + c.compileIfVarSubN(con, node.Args[pos+2].String()) +func (c *CTemplateSet) compareFunc(con CContext, pos int, n *parse.CommandNode, compare string) (out string) { + c.dumpSymbol(pos, n, compare) + return c.compileIfVarSubN(con, n.Args[pos+1].String()) + " " + compare + " " + c.compileIfVarSubN(con, n.Args[pos+2].String()) } -func (c *CTemplateSet) simpleMath(con CContext, pos int, node *parse.CommandNode, symbol string) (out string, val reflect.Value) { - leftParam, val2 := c.compileIfVarSub(con, node.Args[pos+1].String()) - rightParam, val3 := c.compileIfVarSub(con, node.Args[pos+2].String()) +func (c *CTemplateSet) simpleMath(con CContext, pos int, n *parse.CommandNode, symbol string) (out string, val reflect.Value) { + leftParam, val2 := c.compileIfVarSub(con, n.Args[pos+1].String()) + rightParam, val3 := c.compileIfVarSub(con, n.Args[pos+2].String()) if val2.IsValid() { val = val2 } else if val3.IsValid() { @@ -1048,7 +1049,7 @@ func (c *CTemplateSet) simpleMath(con CContext, pos int, node *parse.CommandNode numSample := 1 val = reflect.ValueOf(numSample) } - c.dumpSymbol(pos, node, symbol) + c.dumpSymbol(pos, n, symbol) return leftParam + " " + symbol + " " + rightParam, val } @@ -1097,7 +1098,7 @@ ArgLoop: for pos := 0; pos < len(node.Args); pos++ { id := node.Args[pos] c.detail("pos:", pos) - c.detail("ID:", id) + c.detail("id:", id) switch id.String() { case "not": out += "!" @@ -1144,6 +1145,14 @@ ArgLoop: val = val3 // TODO: Refactor this + if leftParam[0] == '"' { + leftParam = strings.TrimSuffix(strings.TrimPrefix(leftParam, "\""), "\"") + id, ok := c.config.DockToID[leftParam] + if ok { + litString("c.BuildWidget2("+strconv.Itoa(id)+","+rightParam+")", false) + break ArgLoop + } + } litString("c.BuildWidget("+leftParam+","+rightParam+")", false) break ArgLoop case "hasWidgets": @@ -1621,8 +1630,8 @@ func (c *CTemplateSet) compileVarSub(con CContext, varname string, val reflect.V } } - c.detail("varname: ", varname) - c.detail("assLines: ", assLines) + c.detail("varname:", varname) + c.detail("assLines:", assLines) var base string switch val.Kind() { case reflect.Int: @@ -1716,7 +1725,7 @@ func (c *CTemplateSet) compileVarSub(con CContext, varname string, val reflect.V c.logger.Println("Unknown Type:", val.Type().Name()) panic("-- I don't know what this variable's type is o.o\n") } - c.detail("base: ", base) + c.detail("base:", base) if assLines == "" { con.Push("varsub", base) } else { @@ -1893,12 +1902,12 @@ func (c *CTemplateSet) compileSubTemplate(pcon CContext, node *parse.TemplateNod c.detailf("c.overridenRoots: %+v\n", c.overridenRoots) } -func (c *CTemplateSet) loadTemplate(fileDir string, name string) (content string, err error) { +func (c *CTemplateSet) loadTemplate(fileDir, name string) (content string, err error) { c.dumpCall("loadTemplate", fileDir, name) - c.detail("c.themeName: ", c.themeName) + c.detail("c.themeName:", c.themeName) if c.themeName != "" { t := "./themes/" + c.themeName + "/overrides/" + name - c.detail("per-theme override: ", true) + c.detail("per-theme override:", true) res, err := ioutil.ReadFile(t) if err == nil { content = string(res) @@ -1907,13 +1916,13 @@ func (c *CTemplateSet) loadTemplate(fileDir string, name string) (content string } return content, nil } - c.detail("override err: ", err) + c.detail("override err:", err) } res, err := ioutil.ReadFile(c.fileDir + "overrides/" + name) if err != nil { - c.detail("override path: ", c.fileDir+"overrides/"+name) - c.detail("override err: ", err) + c.detail("override path:", c.fileDir+"overrides/"+name) + c.detail("override err:", err) res, err = ioutil.ReadFile(c.fileDir + name) if err != nil { return "", err diff --git a/common/theme.go b/common/theme.go index a340192d..e9a955ee 100644 --- a/common/theme.go +++ b/common/theme.go @@ -43,6 +43,7 @@ type Theme struct { Tag string URL string Docks []string // Allowed Values: leftSidebar, rightSidebar, footer + DocksID []int // Integer versions of Docks to try to get a speed boost in BuildWidget() Settings map[string]ThemeSetting IntTmplHandle *htmpl.Template // TODO: Do we really need both OverridenTemplates AND OverridenMap? @@ -58,6 +59,7 @@ type Theme struct { // TODO: Implement this MapTmplToDock map[string]ThemeMapTmplToDock // map[dockName]data RunOnDock func(string) string //(dock string) (sbody string) + RunOnDockID func(int) string //(dock int) (sbody string) // This variable should only be set and unset by the system, not the theme meta file // TODO: Should we phase out Active and make the default theme store the primary source of truth? @@ -381,6 +383,23 @@ func (t Theme) BuildDock(dock string) (sbody string) { return "" } +func (t Theme) HasDockByID(id int) bool { + for _, dock := range t.DocksID { + if dock == id { + return true + } + } + return false +} + +func (t Theme) BuildDockByID(id int) (sbody string) { + runOnDock := t.RunOnDockID + if runOnDock != nil { + return runOnDock(id) + } + return "" +} + type GzipResponseWriter struct { io.Writer http.ResponseWriter diff --git a/common/theme_list.go b/common/theme_list.go index 2f34abd1..76fd8efd 100644 --- a/common/theme_list.go +++ b/common/theme_list.go @@ -76,7 +76,7 @@ func NewThemeList() (themes ThemeList, err error) { return themes, err } - theme := &Theme{Name: ""} + theme := &Theme{} err = json.Unmarshal(themeFile, theme) if err != nil { return themes, err @@ -97,7 +97,7 @@ func NewThemeList() (themes ThemeList, err error) { if err != nil { return themes, err } - theme = &Theme{Name: "", Path: theme.Path} + theme = &Theme{Path: theme.Path} err = json.Unmarshal(themeFile, theme) if err != nil { return themes, err @@ -179,21 +179,30 @@ func NewThemeList() (themes ThemeList, err error) { for i, res := range theme.Resources { ext := filepath.Ext(res.Name) - if ext == ".css" { + switch ext { + case ".css": res.Type = ResTypeSheet - } else if ext == ".js" { + case ".js": res.Type = ResTypeScript } - if res.Location == "global" { + switch res.Location { + case "global": res.LocID = LocGlobal - } else if res.Location == "frontend" { + case "frontend": res.LocID = LocFront - } else if res.Location == "panel" { + case "panel": res.LocID = LocPanel } theme.Resources[i] = res } + for _, dock := range theme.Docks { + id, ok := DockToID[dock] + if ok { + theme.DocksID = append(theme.DocksID, id) + } + } + // TODO: Bind the built template, or an interpreted one for any dock overrides this theme has themes[theme.Name] = theme diff --git a/common/widgets.go b/common/widgets.go index 7e67b62a..27d04683 100644 --- a/common/widgets.go +++ b/common/widgets.go @@ -221,6 +221,61 @@ func BuildWidget(dock string, h *Header) (sbody string) { return sbody } +var DockToID = map[string]int{ + "leftOfNav": 0, + "rightOfNav": 1, + "topMenu": 2, + "rightSidebar": 3, + "footer": 4, +} + +func BuildWidget2(dock int, h *Header) (sbody string) { + if !h.Theme.HasDockByID(dock) { + return "" + } + // Let themes forcibly override this slot + sbody = h.Theme.BuildDockByID(dock) + if sbody != "" { + return sbody + } + + var widgets []*Widget + switch dock { + case 0: + widgets = Docks.LeftOfNav + case 1: + widgets = Docks.RightOfNav + case 2: + // 1 = id for the default menu + mhold, err := Menus.Get(1) + if err == nil { + err := mhold.Build(h.Writer, h.CurrentUser, h.Path) + if err != nil { + LogError(err) + } + } + return "" + case 3: + widgets = Docks.RightSidebar.Items + case 4: + widgets = Docks.Footer.Items + } + + for _, widget := range widgets { + if !widget.Enabled { + continue + } + if widget.Allowed(h.Zone, h.ZoneID) { + item, err := widget.Build(h) + if err != nil { + LogError(err) + } + sbody += item + } + } + return sbody +} + func getDockWidgets(dock string) (widgets []*Widget, err error) { rows, err := widgetStmts.getDockList.Query(dock) if err != nil { diff --git a/templates/register.html b/templates/register.html index e615da23..3a0b386a 100644 --- a/templates/register.html +++ b/templates/register.html @@ -35,4 +35,4 @@ -{{template "footer.html" . }} +{{template "footer.html" . }} \ No newline at end of file