Speed up template compilation by not building the same parse trees multiple times.
Compile panel_debug. Add the ability to print int8, int16, int32, uint, uint8, uint16, uint32 and uint64 in compiled templates. Add the ability to pass string nodes to subtemplates in the template compiler. Fix bunit in the template compiler. Shorten some things.
This commit is contained in:
parent
f76af39a11
commit
df6e268a06
|
@ -6,14 +6,16 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common/alerts"
|
"github.com/Azareal/Gosora/common/alerts"
|
||||||
"github.com/Azareal/Gosora/common/phrases"
|
p "github.com/Azareal/Gosora/common/phrases"
|
||||||
"github.com/Azareal/Gosora/common/templates"
|
"github.com/Azareal/Gosora/common/templates"
|
||||||
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Ctemplates []string // TODO: Use this to filter out top level templates we don't need
|
var Ctemplates []string // TODO: Use this to filter out top level templates we don't need
|
||||||
|
@ -184,8 +186,7 @@ func CompileTemplates() error {
|
||||||
|
|
||||||
log.Print("Compiling the default templates")
|
log.Print("Compiling the default templates")
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
err := compileTemplates(&wg, c, "")
|
if err := compileTemplates(&wg, c, ""); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
oroots := c.GetOverridenRoots()
|
oroots := c.GetOverridenRoots()
|
||||||
|
@ -198,7 +199,7 @@ func CompileTemplates() error {
|
||||||
c.SetPerThemeTmpls(tmpls)
|
c.SetPerThemeTmpls(tmpls)
|
||||||
log.Print("theme: ", theme)
|
log.Print("theme: ", theme)
|
||||||
log.Printf("perThemeTmpls: %+v\n", tmpls)
|
log.Printf("perThemeTmpls: %+v\n", tmpls)
|
||||||
err = compileTemplates(&wg, c, theme)
|
err := compileTemplates(&wg, c, theme)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -207,30 +208,30 @@ func CompileTemplates() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileCommons(c *tmpl.CTemplateSet, header *Header, header2 *Header, forumList []Forum, out TItemHold) error {
|
func compileCommons(c *tmpl.CTemplateSet, head *Header, head2 *Header, forumList []Forum, o TItemHold) error {
|
||||||
// TODO: Add support for interface{}s
|
// TODO: Add support for interface{}s
|
||||||
_, user2, user3 := tmplInitUsers()
|
_, user2, user3 := tmplInitUsers()
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
// Convienience function to save a line here and there
|
// Convienience function to save a line here and there
|
||||||
htitle := func(name string) *Header {
|
htitle := func(name string) *Header {
|
||||||
header.Title = name
|
head.Title = name
|
||||||
return header
|
return head
|
||||||
}
|
}
|
||||||
/*htitle2 := func(name string) *Header {
|
/*htitle2 := func(name string) *Header {
|
||||||
header2.Title = name
|
head2.Title = name
|
||||||
return header2
|
return head2
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
var topicsList []*TopicsRow
|
var topicsList []*TopicsRow
|
||||||
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})
|
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}}
|
topicListPage := TopicListPage{htitle("Topic List"), topicsList, forumList, Config.DefaultForum, TopicListSort{"lastupdated", false}, Paginator{[]int{1}, 1, 1}}
|
||||||
out.Add("topics", "c.TopicListPage", topicListPage)
|
o.Add("topics", "c.TopicListPage", topicListPage)
|
||||||
|
|
||||||
forumItem := BlankForum(1, "general-forum.1", "General Forum", "Where the general stuff happens", true, "all", 0, "", 0)
|
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}}
|
forumPage := ForumPage{htitle("General Forum"), topicsList, forumItem, Paginator{[]int{1}, 1, 1}}
|
||||||
out.Add("forum", "c.ForumPage", forumPage)
|
o.Add("forum", "c.ForumPage", forumPage)
|
||||||
out.Add("forums", "c.ForumsPage", ForumsPage{htitle("Forum List"), forumList})
|
o.Add("forums", "c.ForumsPage", ForumsPage{htitle("Forum List"), forumList})
|
||||||
|
|
||||||
poll := Poll{ID: 1, Type: 0, Options: map[int]string{0: "Nothing", 1: "Something"}, Results: map[int]int{0: 5, 1: 2}, QuickOptions: []PollOption{
|
poll := Poll{ID: 1, Type: 0, Options: map[int]string{0: "Nothing", 1: "Something"}, Results: map[int]int{0: 5, 1: 2}, QuickOptions: []PollOption{
|
||||||
PollOption{0, "Nothing"},
|
PollOption{0, "Nothing"},
|
||||||
|
@ -247,8 +248,8 @@ func compileCommons(c *tmpl.CTemplateSet, header *Header, header2 *Header, forum
|
||||||
replyList = append(replyList, ru)
|
replyList = append(replyList, ru)
|
||||||
tpage := TopicPage{htitle("Topic Name"), replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, poll, Paginator{[]int{1}, 1, 1}}
|
tpage := TopicPage{htitle("Topic Name"), replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, poll, Paginator{[]int{1}, 1, 1}}
|
||||||
tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID)
|
tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID)
|
||||||
out.Add("topic", "c.TopicPage", tpage)
|
o.Add("topic", "c.TopicPage", tpage)
|
||||||
out.Add("topic_alt", "c.TopicPage", tpage)
|
o.Add("topic_alt", "c.TopicPage", tpage)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,6 +363,16 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
|
||||||
t.AddStd("panel", "c.Panel", Panel{basePage, "panel_dashboard_right", "", "panel_dashboard", inter})
|
t.AddStd("panel", "c.Panel", Panel{basePage, "panel_dashboard_right", "", "panel_dashboard", inter})
|
||||||
ges := []GridElement{GridElement{"","", "", 1, "grid_istat", "", "", ""}}
|
ges := []GridElement{GridElement{"","", "", 1, "grid_istat", "", "", ""}}
|
||||||
t.AddStd("panel_dashboard", "c.DashGrids", DashGrids{ges,ges})
|
t.AddStd("panel_dashboard", "c.DashGrids", DashGrids{ges,ges})
|
||||||
|
|
||||||
|
goVersion := runtime.Version()
|
||||||
|
dbVersion := qgen.Builder.DbVersion()
|
||||||
|
var memStats runtime.MemStats
|
||||||
|
runtime.ReadMemStats(&memStats)
|
||||||
|
debugCache := DebugPageCache{1, 1, 1, 2, 2, 2, true}
|
||||||
|
debugDatabase := DebugPageDatabase{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
|
||||||
|
debugDisk := DebugPageDisk{1,1,1,1,1,1}
|
||||||
|
dpage := PanelDebugPage{basePage, goVersion, dbVersion, "0s", 1, qgen.Builder.GetAdapter().GetName(), 1, 1, memStats, debugCache, debugDatabase, debugDisk}
|
||||||
|
t.AddStd("panel_debug", "c.PanelDebugPage", dpage)
|
||||||
//t.AddStd("panel_analytics", "c.PanelAnalytics", Panel{basePage, "panel_dashboard_right","panel_dashboard", inter})
|
//t.AddStd("panel_analytics", "c.PanelAnalytics", Panel{basePage, "panel_dashboard_right","panel_dashboard", inter})
|
||||||
|
|
||||||
writeTemplate := func(name string, content interface{}) {
|
writeTemplate := func(name string, content interface{}) {
|
||||||
|
@ -732,7 +743,7 @@ func initDefaultTmplFuncMap() {
|
||||||
panic("phraseNameInt is not a string")
|
panic("phraseNameInt is not a string")
|
||||||
}
|
}
|
||||||
// TODO: Log non-existent phrases?
|
// TODO: Log non-existent phrases?
|
||||||
return template.HTML(phrases.GetTmplPhrase(phraseName))
|
return template.HTML(p.GetTmplPhrase(phraseName))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement this in the template generator too
|
// TODO: Implement this in the template generator too
|
||||||
|
@ -743,7 +754,7 @@ func initDefaultTmplFuncMap() {
|
||||||
}
|
}
|
||||||
// TODO: Log non-existent phrases?
|
// TODO: Log non-existent phrases?
|
||||||
// TODO: Optimise TmplPhrasef so we don't use slow Sprintf there
|
// TODO: Optimise TmplPhrasef so we don't use slow Sprintf there
|
||||||
return template.HTML(phrases.GetTmplPhrasef(phraseName, args...))
|
return template.HTML(p.GetTmplPhrasef(phraseName, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
fmap["level"] = func(levelInt interface{}) interface{} {
|
fmap["level"] = func(levelInt interface{}) interface{} {
|
||||||
|
@ -751,7 +762,7 @@ func initDefaultTmplFuncMap() {
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("levelInt is not an integer")
|
panic("levelInt is not an integer")
|
||||||
}
|
}
|
||||||
return template.HTML(phrases.GetLevelPhrase(level))
|
return template.HTML(p.GetLevelPhrase(level))
|
||||||
}
|
}
|
||||||
|
|
||||||
fmap["bunit"] = func(byteInt interface{}) interface{} {
|
fmap["bunit"] = func(byteInt interface{}) interface{} {
|
||||||
|
|
|
@ -218,18 +218,15 @@ import "errors"
|
||||||
|
|
||||||
if !c.config.SkipInitBlock {
|
if !c.config.SkipInitBlock {
|
||||||
stub += "// nolint\nfunc init() {\n"
|
stub += "// nolint\nfunc init() {\n"
|
||||||
|
|
||||||
if !c.config.SkipHandles && c.themeName == "" {
|
if !c.config.SkipHandles && c.themeName == "" {
|
||||||
stub += "\tc.Template_" + fname + "_handle = Template_" + fname + "\n"
|
stub += "\tc.Template_" + fname + "_handle = Template_" + fname + "\n"
|
||||||
stub += "\tc.Ctemplates = append(c.Ctemplates,\"" + fname + "\")\n"
|
stub += "\tc.Ctemplates = append(c.Ctemplates,\"" + fname + "\")\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.config.SkipTmplPtrMap {
|
if !c.config.SkipTmplPtrMap {
|
||||||
stub += "tmpl := Template_" + fname + "\n"
|
stub += "tmpl := Template_" + fname + "\n"
|
||||||
stub += "\tc.TmplPtrMap[\"" + fname + "\"] = &tmpl\n"
|
stub += "\tc.TmplPtrMap[\"" + fname + "\"] = &tmpl\n"
|
||||||
stub += "\tc.TmplPtrMap[\"o_" + fname + "\"] = tmpl\n"
|
stub += "\tc.TmplPtrMap[\"o_" + fname + "\"] = tmpl\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
stub += "}\n\n"
|
stub += "}\n\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,8 +284,7 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
fmt.Println(r)
|
fmt.Println(r)
|
||||||
debug.PrintStack()
|
debug.PrintStack()
|
||||||
err := c.loggerf.Sync()
|
if err := c.loggerf.Sync(); err != nil {
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
log.Fatal("")
|
log.Fatal("")
|
||||||
|
@ -311,13 +307,14 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
|
||||||
c.localDispStructIndex = 0
|
c.localDispStructIndex = 0
|
||||||
c.stats = make(map[string]int)
|
c.stats = make(map[string]int)
|
||||||
|
|
||||||
tree := parse.New(name, c.funcMap)
|
//tree := parse.New(name, c.funcMap)
|
||||||
treeSet := make(map[string]*parse.Tree)
|
//treeSet := make(map[string]*parse.Tree)
|
||||||
tree, err = tree.Parse(content, "{{", "}}", treeSet, c.funcMap)
|
treeSet, err := parse.Parse(name, content, "{{", "}}", c.funcMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
c.detail(name)
|
c.detail(name)
|
||||||
|
c.detailf("treeSet: %+v\n", treeSet)
|
||||||
|
|
||||||
fname := strings.TrimSuffix(name, filepath.Ext(name))
|
fname := strings.TrimSuffix(name, filepath.Ext(name))
|
||||||
if c.themeName != "" {
|
if c.themeName != "" {
|
||||||
|
@ -374,8 +371,21 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
|
||||||
TemplateName: fname,
|
TemplateName: fname,
|
||||||
OutBuf: &outBuf,
|
OutBuf: &outBuf,
|
||||||
}
|
}
|
||||||
c.templateList = map[string]*parse.Tree{fname: tree}
|
|
||||||
c.detail(c.templateList)
|
c.templateList = map[string]*parse.Tree{}
|
||||||
|
for nname, tree := range treeSet {
|
||||||
|
if name == nname {
|
||||||
|
c.templateList[fname] = tree
|
||||||
|
} else {
|
||||||
|
if !strings.HasPrefix(nname, ".html") {
|
||||||
|
c.templateList[nname] = tree
|
||||||
|
} else {
|
||||||
|
c.templateList[strings.TrimSuffix(nname, ".html")] = tree
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.detailf("c.templateList: %+v\n", c.templateList)
|
||||||
|
|
||||||
c.localVars = make(map[string]map[string]VarItemReflect)
|
c.localVars = make(map[string]map[string]VarItemReflect)
|
||||||
c.localVars[fname] = make(map[string]VarItemReflect)
|
c.localVars[fname] = make(map[string]VarItemReflect)
|
||||||
c.localVars[fname]["."] = VarItemReflect{".", con.VarHolder, con.HoldReflect}
|
c.localVars[fname]["."] = VarItemReflect{".", con.VarHolder, con.HoldReflect}
|
||||||
|
@ -392,8 +402,14 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
|
||||||
//}
|
//}
|
||||||
//c.detailf("c: %+v\n", c)
|
//c.detailf("c: %+v\n", c)
|
||||||
|
|
||||||
|
c.detailf("name: %+v\n", name)
|
||||||
|
c.detailf("fname: %+v\n", fname)
|
||||||
startIndex := con.StartTemplate("")
|
startIndex := con.StartTemplate("")
|
||||||
c.rootIterate(c.templateList[fname], con)
|
ttree := c.templateList[fname]
|
||||||
|
if ttree == nil {
|
||||||
|
panic("ttree is nil")
|
||||||
|
}
|
||||||
|
c.rootIterate(ttree, con)
|
||||||
con.EndTemplate("")
|
con.EndTemplate("")
|
||||||
c.afterTemplate(con, startIndex)
|
c.afterTemplate(con, startIndex)
|
||||||
//c.templateFragmentCount[fname] = c.fragmentCursor[fname] + 1
|
//c.templateFragmentCount[fname] = c.fragmentCursor[fname] + 1
|
||||||
|
@ -574,6 +590,10 @@ w.Write([]byte(`, " + ", -1)
|
||||||
|
|
||||||
func (c *CTemplateSet) rootIterate(tree *parse.Tree, con CContext) {
|
func (c *CTemplateSet) rootIterate(tree *parse.Tree, con CContext) {
|
||||||
c.dumpCall("rootIterate", tree, con)
|
c.dumpCall("rootIterate", tree, con)
|
||||||
|
if tree.Root == nil {
|
||||||
|
c.detailf("tree: %+v\n", tree)
|
||||||
|
panic("tree root node is empty")
|
||||||
|
}
|
||||||
c.detail(tree.Root)
|
c.detail(tree.Root)
|
||||||
for _, node := range tree.Root.Nodes {
|
for _, node := range tree.Root.Nodes {
|
||||||
c.detail("Node:", node.String())
|
c.detail("Node:", node.String())
|
||||||
|
@ -1195,8 +1215,9 @@ ArgLoop:
|
||||||
}
|
}
|
||||||
leftParam, _ := c.compileIfVarSub(con, leftOperand)
|
leftParam, _ := c.compileIfVarSub(con, leftOperand)
|
||||||
out = "{\nbyteFloat, unit := c.ConvertByteUnit(float64(" + leftParam + "))\n"
|
out = "{\nbyteFloat, unit := c.ConvertByteUnit(float64(" + leftParam + "))\n"
|
||||||
out += "w.Write(fmt.Sprintf(\"%.1f\", byteFloat) + unit)\n"
|
out += "w.Write(StringToBytes(fmt.Sprintf(\"%.1f\", byteFloat) + unit))\n}\n"
|
||||||
literal = true
|
literal = true
|
||||||
|
c.importMap["fmt"] = "fmt"
|
||||||
break ArgLoop
|
break ArgLoop
|
||||||
case "abstime":
|
case "abstime":
|
||||||
// TODO: Implement level literals
|
// TODO: Implement level literals
|
||||||
|
@ -1601,9 +1622,18 @@ func (c *CTemplateSet) compileVarSub(con CContext, varname string, val reflect.V
|
||||||
if c.guestOnly && base == "StringToBytes("+con.RootHolder+".CurrentUser.Session))" {
|
if c.guestOnly && base == "StringToBytes("+con.RootHolder+".CurrentUser.Session))" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
case reflect.Int8, reflect.Int16, reflect.Int32:
|
||||||
|
c.importMap["strconv"] = "strconv"
|
||||||
|
base = "StringToBytes(strconv.FormatInt(int64(" + varname + "), 10))"
|
||||||
case reflect.Int64:
|
case reflect.Int64:
|
||||||
c.importMap["strconv"] = "strconv"
|
c.importMap["strconv"] = "strconv"
|
||||||
base = "StringToBytes(strconv.FormatInt(" + varname + ", 10))"
|
base = "StringToBytes(strconv.FormatInt(" + varname + ", 10))"
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
|
||||||
|
c.importMap["strconv"] = "strconv"
|
||||||
|
base = "StringToBytes(strconv.FormatUint(uint64(" + varname + "), 10))"
|
||||||
|
case reflect.Uint64:
|
||||||
|
c.importMap["strconv"] = "strconv"
|
||||||
|
base = "StringToBytes(strconv.FormatUint(" + varname + ", 10))"
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
// TODO: Avoid clashing with other packages which have structs named Time
|
// TODO: Avoid clashing with other packages which have structs named Time
|
||||||
if val.Type().Name() == "Time" {
|
if val.Type().Name() == "Time" {
|
||||||
|
@ -1638,19 +1668,6 @@ func (c *CTemplateSet) compileSubTemplate(pcon CContext, node *parse.TemplateNod
|
||||||
defer c.retCall("compileSubTemplate")
|
defer c.retCall("compileSubTemplate")
|
||||||
c.detail("Template Node: ", node.Name)
|
c.detail("Template Node: ", node.Name)
|
||||||
|
|
||||||
// TODO: Cascade errors back up the tree to the caller?
|
|
||||||
content, err := c.loadTemplate(c.fileDir, node.Name)
|
|
||||||
if err != nil {
|
|
||||||
c.logger.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tree := parse.New(node.Name, c.funcMap)
|
|
||||||
var treeSet = make(map[string]*parse.Tree)
|
|
||||||
tree, err = tree.Parse(content, "{{", "}}", treeSet, c.funcMap)
|
|
||||||
if err != nil {
|
|
||||||
c.logger.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fname := strings.TrimSuffix(node.Name, filepath.Ext(node.Name))
|
fname := strings.TrimSuffix(node.Name, filepath.Ext(node.Name))
|
||||||
if c.themeName != "" {
|
if c.themeName != "" {
|
||||||
_, ok := c.perThemeTmpls[fname]
|
_, ok := c.perThemeTmpls[fname]
|
||||||
|
@ -1666,6 +1683,36 @@ func (c *CTemplateSet) compileSubTemplate(pcon CContext, node *parse.TemplateNod
|
||||||
fname += "_member"
|
fname += "_member"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, ok := c.templateList[fname]
|
||||||
|
if !ok {
|
||||||
|
// TODO: Cascade errors back up the tree to the caller?
|
||||||
|
content, err := c.loadTemplate(c.fileDir, node.Name)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
//tree := parse.New(node.Name, c.funcMap)
|
||||||
|
//treeSet := make(map[string]*parse.Tree)
|
||||||
|
treeSet, err := parse.Parse(node.Name, content, "{{", "}}", c.funcMap)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Fatal(err)
|
||||||
|
}
|
||||||
|
c.detailf("treeSet: %+v\n", treeSet)
|
||||||
|
|
||||||
|
for nname, tree := range treeSet {
|
||||||
|
if node.Name == nname {
|
||||||
|
c.templateList[fname] = tree
|
||||||
|
} else {
|
||||||
|
if !strings.HasPrefix(nname, ".html") {
|
||||||
|
c.templateList[nname] = tree
|
||||||
|
} else {
|
||||||
|
c.templateList[strings.TrimSuffix(nname, ".html")] = tree
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.detailf("c.templateList: %+v\n", c.templateList)
|
||||||
|
}
|
||||||
|
|
||||||
con := pcon
|
con := pcon
|
||||||
con.VarHolder = "tmpl_" + fname + "_vars"
|
con.VarHolder = "tmpl_" + fname + "_vars"
|
||||||
con.TemplateName = fname
|
con.TemplateName = fname
|
||||||
|
@ -1675,7 +1722,6 @@ func (c *CTemplateSet) compileSubTemplate(pcon CContext, node *parse.TemplateNod
|
||||||
case *parse.FieldNode:
|
case *parse.FieldNode:
|
||||||
// TODO: Incomplete but it should cover the basics
|
// TODO: Incomplete but it should cover the basics
|
||||||
cur := pcon.HoldReflect
|
cur := pcon.HoldReflect
|
||||||
|
|
||||||
var varBit string
|
var varBit string
|
||||||
if cur.Kind() == reflect.Interface {
|
if cur.Kind() == reflect.Interface {
|
||||||
cur = cur.Elem()
|
cur = cur.Elem()
|
||||||
|
@ -1707,6 +1753,11 @@ func (c *CTemplateSet) compileSubTemplate(pcon CContext, node *parse.TemplateNod
|
||||||
}
|
}
|
||||||
con.VarHolder = pcon.VarHolder + varBit
|
con.VarHolder = pcon.VarHolder + varBit
|
||||||
con.HoldReflect = cur
|
con.HoldReflect = cur
|
||||||
|
case *parse.StringNode:
|
||||||
|
//con.VarHolder = pcon.VarHolder
|
||||||
|
//con.HoldReflect = pcon.HoldReflect
|
||||||
|
con.VarHolder = p.Quoted
|
||||||
|
con.HoldReflect = reflect.ValueOf(p.Quoted)
|
||||||
case *parse.DotNode:
|
case *parse.DotNode:
|
||||||
con.VarHolder = pcon.VarHolder
|
con.VarHolder = pcon.VarHolder
|
||||||
con.HoldReflect = pcon.HoldReflect
|
con.HoldReflect = pcon.HoldReflect
|
||||||
|
@ -1730,7 +1781,7 @@ func (c *CTemplateSet) compileSubTemplate(pcon CContext, node *parse.TemplateNod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.templateList[fname] = tree
|
//c.templateList[fname] = tree
|
||||||
subtree := c.templateList[fname]
|
subtree := c.templateList[fname]
|
||||||
c.detail("subtree.Root", subtree.Root)
|
c.detail("subtree.Root", subtree.Root)
|
||||||
c.localVars[fname] = make(map[string]VarItemReflect)
|
c.localVars[fname] = make(map[string]VarItemReflect)
|
||||||
|
@ -1746,9 +1797,7 @@ func (c *CTemplateSet) compileSubTemplate(pcon CContext, node *parse.TemplateNod
|
||||||
c.rootIterate(subtree, con)
|
c.rootIterate(subtree, con)
|
||||||
con.EndTemplate(endBit)
|
con.EndTemplate(endBit)
|
||||||
//c.templateFragmentCount[fname] = c.fragmentCursor[fname] + 1
|
//c.templateFragmentCount[fname] = c.fragmentCursor[fname] + 1
|
||||||
|
if _, ok := c.fragOnce[fname]; !ok {
|
||||||
_, ok := c.fragOnce[fname]
|
|
||||||
if !ok {
|
|
||||||
c.fragOnce[fname] = true
|
c.fragOnce[fname] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1785,11 +1834,11 @@ func (c *CTemplateSet) compileSubTemplate(pcon CContext, node *parse.TemplateNod
|
||||||
|
|
||||||
func (c *CTemplateSet) loadTemplate(fileDir string, name string) (content string, err error) {
|
func (c *CTemplateSet) loadTemplate(fileDir string, name string) (content string, err error) {
|
||||||
c.dumpCall("loadTemplate", fileDir, name)
|
c.dumpCall("loadTemplate", fileDir, name)
|
||||||
|
|
||||||
c.detail("c.themeName: ", c.themeName)
|
c.detail("c.themeName: ", c.themeName)
|
||||||
if c.themeName != "" {
|
if c.themeName != "" {
|
||||||
c.detail("per-theme override: ", "./themes/"+c.themeName+"/overrides/"+name)
|
t := "./themes/" + c.themeName + "/overrides/" + name
|
||||||
res, err := ioutil.ReadFile("./themes/" + c.themeName + "/overrides/" + name)
|
c.detail("per-theme override: ", true)
|
||||||
|
res, err := ioutil.ReadFile(t)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
content = string(res)
|
content = string(res)
|
||||||
if c.config.Minify {
|
if c.config.Minify {
|
||||||
|
@ -1820,11 +1869,10 @@ func (c *CTemplateSet) afterTemplate(con CContext, startIndex int) {
|
||||||
c.dumpCall("afterTemplate", con, startIndex)
|
c.dumpCall("afterTemplate", con, startIndex)
|
||||||
defer c.retCall("afterTemplate")
|
defer c.retCall("afterTemplate")
|
||||||
|
|
||||||
var loopDepth = 0
|
loopDepth := 0
|
||||||
var outBuf = *con.OutBuf
|
var outBuf = *con.OutBuf
|
||||||
var varcounts = make(map[string]int)
|
varcounts := make(map[string]int)
|
||||||
var loopStart = startIndex
|
loopStart := startIndex
|
||||||
|
|
||||||
if outBuf[startIndex].Type == "startloop" && (len(outBuf) > startIndex+1) {
|
if outBuf[startIndex].Type == "startloop" && (len(outBuf) > startIndex+1) {
|
||||||
loopStart++
|
loopStart++
|
||||||
}
|
}
|
||||||
|
@ -1852,7 +1900,7 @@ func (c *CTemplateSet) afterTemplate(con CContext, startIndex int) {
|
||||||
|
|
||||||
var varstr string
|
var varstr string
|
||||||
var i int
|
var i int
|
||||||
var varmap = make(map[string]int)
|
varmap := make(map[string]int)
|
||||||
for name, count := range varcounts {
|
for name, count := range varcounts {
|
||||||
if count > 1 {
|
if count > 1 {
|
||||||
varstr += "var cached_var_" + strconv.Itoa(i) + " = " + name + "\n"
|
varstr += "var cached_var_" + strconv.Itoa(i) + " = " + name + "\n"
|
||||||
|
|
|
@ -18,10 +18,10 @@ func Debug(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
|
|
||||||
goVersion := runtime.Version()
|
goVersion := runtime.Version()
|
||||||
dbVersion := qgen.Builder.DbVersion()
|
dbVersion := qgen.Builder.DbVersion()
|
||||||
var uptime string
|
|
||||||
upDuration := time.Since(c.StartTime)
|
upDuration := time.Since(c.StartTime)
|
||||||
hours := int(upDuration.Hours())
|
hours := int(upDuration.Hours())
|
||||||
minutes := int(upDuration.Minutes())
|
minutes := int(upDuration.Minutes())
|
||||||
|
var uptime string
|
||||||
if hours > 24 {
|
if hours > 24 {
|
||||||
days := hours / 24
|
days := hours / 24
|
||||||
hours -= days * 24
|
hours -= days * 24
|
||||||
|
@ -63,7 +63,7 @@ func Debug(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
debugCache := c.DebugPageCache{tlen, ulen, rlen, tcap, ucap, rcap, topicListThawed}
|
debugCache := c.DebugPageCache{tlen, ulen, rlen, tcap, ucap, rcap, topicListThawed}
|
||||||
|
|
||||||
var fErr error
|
var fErr error
|
||||||
var count = func(tbl string) int {
|
count := func(tbl string) int {
|
||||||
if fErr != nil {
|
if fErr != nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ func Debug(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
|
|
||||||
debugDatabase := c.DebugPageDatabase{c.Topics.Count(),c.Users.Count(),c.Rstore.Count(),c.Prstore.Count(),c.Activity.Count(),c.Likes.Count(),attachs,polls,loginLogs,regLogs,modLogs,adminLogs,views,viewsAgents,viewsForums,viewsLangs,viewsReferrers,viewsSystems,postChunks,topicChunks}
|
debugDatabase := c.DebugPageDatabase{c.Topics.Count(),c.Users.Count(),c.Rstore.Count(),c.Prstore.Count(),c.Activity.Count(),c.Likes.Count(),attachs,polls,loginLogs,regLogs,modLogs,adminLogs,views,viewsAgents,viewsForums,viewsLangs,viewsReferrers,viewsSystems,postChunks,topicChunks}
|
||||||
|
|
||||||
var dirSize = func(path string) int {
|
dirSize := func(path string) int {
|
||||||
if fErr != nil {
|
if fErr != nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>{{lang "panel_user_name"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "panel_user_name"}}</a></div>
|
||||||
<div class="formitem"><input form="user_form" name="user-name" type="text" value="{{.Something.Name}}" placeholder="{{lang "panel_user_name_placeholder"}}" /></div>
|
<div class="formitem"><input form="user_form" name="user-name" type="text" value="{{.Something.Name}}" placeholder="{{lang "panel_user_name_placeholder"}}" autocomplete="off" /></div>
|
||||||
</div>
|
</div>
|
||||||
{{if .CurrentUser.Perms.EditUserPassword}}<div class="formrow">
|
{{if .CurrentUser.Perms.EditUserPassword}}<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>{{lang "panel_user_password"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "panel_user_password"}}</a></div>
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
<div class="formitem formlabel"><a>{{lang "panel_user_group"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "panel_user_group"}}</a></div>
|
||||||
<div class="formitem">
|
<div class="formitem">
|
||||||
<select form="user_form" name="user-group">
|
<select form="user_form" name="user-group">
|
||||||
{{range .ItemList}}<option {{if eq .ID $.Something.Group}}selected {{end}}value="{{.ID}}">{{.Name}}</option>{{end}}
|
{{range .ItemList}}<option{{if eq .ID $.Something.Group}} selected{{end}} value="{{.ID}}">{{.Name}}</option>{{end}}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>{{end}}
|
</div>{{end}}
|
||||||
|
|
|
@ -94,4 +94,4 @@
|
||||||
{{if .CurrentUser.IsAdmin}}<div class="rowitem passive">
|
{{if .CurrentUser.IsAdmin}}<div class="rowitem passive">
|
||||||
<a href="/panel/debug/">{{lang "panel_menu_debug"}}</a>
|
<a href="/panel/debug/">{{lang "panel_menu_debug"}}</a>
|
||||||
</div>{{end}}
|
</div>{{end}}
|
||||||
</div>
|
</div>
|
Loading…
Reference in New Issue