From ffb347a2bbd1f0a7f5a30fdbaa5682525bdf78bb Mon Sep 17 00:00:00 2001 From: astaxie Date: Thu, 12 Sep 2013 17:20:32 +0800 Subject: [PATCH] support nest template --- controller.go | 91 ++++----------------------------------------------- template.go | 65 +++++++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 96 deletions(-) diff --git a/controller.go b/controller.go index bf4be1fa..b93c4db1 100644 --- a/controller.go +++ b/controller.go @@ -16,8 +16,6 @@ import ( "net/http" "net/url" "os" - "path" - "regexp" "strconv" "strings" "time" @@ -127,74 +125,22 @@ func (c *Controller) RenderBytes() ([]byte, error) { if RunMode == "dev" { BuildTemplate(ViewsPath) } - subdir := path.Dir(c.TplNames) - _, file := path.Split(c.TplNames) newbytes := bytes.NewBufferString("") - if _, ok := BeeTemplates[subdir]; !ok { + if _, ok := BeeTemplates[c.TplNames]; !ok { panic("can't find templatefile in the path:" + c.TplNames) return []byte{}, errors.New("can't find templatefile in the path:" + c.TplNames) } - err := BeeTemplates[subdir].ExecuteTemplate(newbytes, file, c.Data) + err := BeeTemplates[c.TplNames].ExecuteTemplate(newbytes, c.TplNames, c.Data) if err != nil { - if terr, ok := err.(*template.Error); ok { - if terr.ErrorCode == template.ErrNoSuchTemplate { - reg := regexp.MustCompile("{{template \"(.+)\"") - filedata, _ := ioutil.ReadFile(path.Join(ViewsPath, c.TplNames)) - a := reg.FindStringSubmatch(string(filedata)) - if len(a) > 1 { - for _, tfile := range a[1:] { - missfile := path.Join(ViewsPath, subdir, tfile) - if ok, _ := FileExists(missfile); ok { - AllTemplateFiles.files[subdir] = append(AllTemplateFiles.files[subdir], missfile) - } - } - for k, v := range AllTemplateFiles.files { - BeeTemplates[k] = template.Must(template.New("beegoTemplate"+k).Delims(TemplateLeft, TemplateRight).Funcs(beegoTplFuncMap).ParseFiles(v...)) - } - err = BeeTemplates[subdir].ExecuteTemplate(newbytes, file, c.Data) - if err != nil { - Trace("template Execute err:", err) - } - goto LayoutTplOk - } - } - } Trace("template Execute err:", err) } - LayoutTplOk: tplcontent, _ := ioutil.ReadAll(newbytes) c.Data["LayoutContent"] = template.HTML(string(tplcontent)) - subdir = path.Dir(c.Layout) - _, file = path.Split(c.Layout) ibytes := bytes.NewBufferString("") - err = BeeTemplates[subdir].ExecuteTemplate(ibytes, file, c.Data) + err = BeeTemplates[c.Layout].ExecuteTemplate(ibytes, c.Layout, c.Data) if err != nil { - if terr, ok := err.(*template.Error); ok { - if terr.ErrorCode == template.ErrNoSuchTemplate { - reg := regexp.MustCompile("{{template \"(.+)\"") - filedata, _ := ioutil.ReadFile(path.Join(ViewsPath, c.Layout)) - a := reg.FindStringSubmatch(string(filedata)) - if len(a) > 1 { - for _, tfile := range a[1:] { - missfile := path.Join(ViewsPath, subdir, tfile) - if ok, _ := FileExists(missfile); ok { - AllTemplateFiles.files[subdir] = append(AllTemplateFiles.files[subdir], missfile) - } - } - for k, v := range AllTemplateFiles.files { - BeeTemplates[k] = template.Must(template.New("beegoTemplate"+k).Delims(TemplateLeft, TemplateRight).Funcs(beegoTplFuncMap).ParseFiles(v...)) - } - err = BeeTemplates[subdir].ExecuteTemplate(ibytes, file, c.Data) - if err != nil { - Trace("template Execute err:", err) - } - goto LayoutOk - } - } - } Trace("template Execute err:", err) } - LayoutOk: icontent, _ := ioutil.ReadAll(ibytes) return icontent, nil } else { @@ -204,40 +150,15 @@ func (c *Controller) RenderBytes() ([]byte, error) { if RunMode == "dev" { BuildTemplate(ViewsPath) } - subdir := path.Dir(c.TplNames) - _, file := path.Split(c.TplNames) ibytes := bytes.NewBufferString("") - if _, ok := BeeTemplates[subdir]; !ok { + if _, ok := BeeTemplates[c.TplNames]; !ok { panic("can't find templatefile in the path:" + c.TplNames) return []byte{}, errors.New("can't find templatefile in the path:" + c.TplNames) } - err := BeeTemplates[subdir].ExecuteTemplate(ibytes, file, c.Data) + err := BeeTemplates[c.TplNames].ExecuteTemplate(ibytes, c.TplNames, c.Data) if err != nil { - if terr, ok := err.(*template.Error); ok { - if terr.ErrorCode == template.ErrNoSuchTemplate { - reg := regexp.MustCompile("{{template \"(.+)\"") - filedata, _ := ioutil.ReadFile(path.Join(ViewsPath, c.TplNames)) - a := reg.FindStringSubmatch(string(filedata)) - if len(a) > 1 { - for _, tfile := range a[1:] { - missfile := path.Join(ViewsPath, subdir, tfile) - if ok, _ := FileExists(missfile); ok { - AllTemplateFiles.files[subdir] = append(AllTemplateFiles.files[subdir], missfile) - } - } - for k, v := range AllTemplateFiles.files { - BeeTemplates[k] = template.Must(template.New("beegoTemplate"+k).Delims(TemplateLeft, TemplateRight).Funcs(beegoTplFuncMap).ParseFiles(v...)) - } - err = BeeTemplates[subdir].ExecuteTemplate(ibytes, file, c.Data) - if err != nil { - Trace("template Execute err:", err) - } - goto TplOk - } - } - } + Trace("template Execute err:", err) } - TplOk: icontent, _ := ioutil.ReadAll(ibytes) return icontent, nil } diff --git a/template.go b/template.go index ffcdc695..86eb1e6a 100644 --- a/template.go +++ b/template.go @@ -6,17 +6,17 @@ import ( "errors" "fmt" "html/template" + "io/ioutil" "os" - "path" "path/filepath" + "regexp" "strings" ) var ( - beegoTplFuncMap template.FuncMap - BeeTemplates map[string]*template.Template - BeeTemplateExt []string - AllTemplateFiles *templatefile + beegoTplFuncMap template.FuncMap + BeeTemplates map[string]*template.Template + BeeTemplateExt []string ) func init() { @@ -63,7 +63,14 @@ func (self *templatefile) visit(paths string, f os.FileInfo, err error) error { replace := strings.NewReplacer("\\", "/") a := []byte(paths) a = a[len([]byte(self.root)):] - subdir := path.Dir(strings.TrimLeft(replace.Replace(string(a)), "/")) + file := strings.TrimLeft(replace.Replace(string(a)), "/") + subdir := filepath.Dir(file) + t, err := getTemplate(file) + if err != nil { + Trace("parse template err:", file, err) + } else { + BeeTemplates[file] = t + } if _, ok := self.files[subdir]; ok { self.files[subdir] = append(self.files[subdir], paths) } else { @@ -101,19 +108,55 @@ func BuildTemplate(dir string) error { return errors.New("dir open err") } } - AllTemplateFiles = &templatefile{ + self := &templatefile{ root: dir, files: make(map[string][]string), } err := filepath.Walk(dir, func(path string, f os.FileInfo, err error) error { - return AllTemplateFiles.visit(path, f, err) + return self.visit(path, f, err) }) if err != nil { fmt.Printf("filepath.Walk() returned %v\n", err) return err } - for k, v := range AllTemplateFiles.files { - BeeTemplates[k] = template.Must(template.New("beegoTemplate"+k).Delims(TemplateLeft, TemplateRight).Funcs(beegoTplFuncMap).ParseFiles(v...)) - } return nil } + +func getTplDeep(file string, t *template.Template) (*template.Template, error) { + fileabspath := filepath.Join(ViewsPath, file) + data, err := ioutil.ReadFile(fileabspath) + if err != nil { + return nil, err + } + t, err = t.New(file).Parse(string(data)) + if err != nil { + return nil, err + } + reg := regexp.MustCompile("{{template \"(.+)\"") + allsub := reg.FindAllStringSubmatch(string(data), -1) + for _, m := range allsub { + if len(m) == 2 { + tlook := t.Lookup(m[1]) + if tlook != nil { + continue + } + if !HasTemplateEXt(m[1]) { + continue + } + t, err = getTplDeep(m[1], t) + if err != nil { + return nil, err + } + } + } + return t, nil +} + +func getTemplate(file string) (t *template.Template, err error) { + t = template.New(file).Delims(TemplateLeft, TemplateRight).Funcs(beegoTplFuncMap) + t, err = getTplDeep(file, t) + if err != nil { + return nil, err + } + return +}