add BuildWidget2 to avoid allocing as many strings in templates for docks
dynamic load /topics/ page where possible reduce boilerplate
This commit is contained in:
parent
d1506d8567
commit
5fe0c8c95b
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue