1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-26 05:01:28 +00:00

support nest template

This commit is contained in:
astaxie 2013-09-12 17:20:32 +08:00
parent 19862725f7
commit ffb347a2bb
2 changed files with 60 additions and 96 deletions

View File

@ -16,8 +16,6 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"path"
"regexp"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -127,74 +125,22 @@ func (c *Controller) RenderBytes() ([]byte, error) {
if RunMode == "dev" { if RunMode == "dev" {
BuildTemplate(ViewsPath) BuildTemplate(ViewsPath)
} }
subdir := path.Dir(c.TplNames)
_, file := path.Split(c.TplNames)
newbytes := bytes.NewBufferString("") newbytes := bytes.NewBufferString("")
if _, ok := BeeTemplates[subdir]; !ok { if _, ok := BeeTemplates[c.TplNames]; !ok {
panic("can't find templatefile in the path:" + c.TplNames) panic("can't find templatefile in the path:" + c.TplNames)
return []byte{}, errors.New("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 { if err != nil {
Trace("template Execute err:", err) Trace("template Execute err:", err)
} }
goto LayoutTplOk
}
}
}
Trace("template Execute err:", err)
}
LayoutTplOk:
tplcontent, _ := ioutil.ReadAll(newbytes) tplcontent, _ := ioutil.ReadAll(newbytes)
c.Data["LayoutContent"] = template.HTML(string(tplcontent)) c.Data["LayoutContent"] = template.HTML(string(tplcontent))
subdir = path.Dir(c.Layout)
_, file = path.Split(c.Layout)
ibytes := bytes.NewBufferString("") 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 { if err != nil {
Trace("template Execute err:", err) Trace("template Execute err:", err)
} }
goto LayoutOk
}
}
}
Trace("template Execute err:", err)
}
LayoutOk:
icontent, _ := ioutil.ReadAll(ibytes) icontent, _ := ioutil.ReadAll(ibytes)
return icontent, nil return icontent, nil
} else { } else {
@ -204,40 +150,15 @@ func (c *Controller) RenderBytes() ([]byte, error) {
if RunMode == "dev" { if RunMode == "dev" {
BuildTemplate(ViewsPath) BuildTemplate(ViewsPath)
} }
subdir := path.Dir(c.TplNames)
_, file := path.Split(c.TplNames)
ibytes := bytes.NewBufferString("") ibytes := bytes.NewBufferString("")
if _, ok := BeeTemplates[subdir]; !ok { if _, ok := BeeTemplates[c.TplNames]; !ok {
panic("can't find templatefile in the path:" + c.TplNames) panic("can't find templatefile in the path:" + c.TplNames)
return []byte{}, errors.New("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 { if err != nil {
Trace("template Execute err:", err) Trace("template Execute err:", err)
} }
goto TplOk
}
}
}
}
TplOk:
icontent, _ := ioutil.ReadAll(ibytes) icontent, _ := ioutil.ReadAll(ibytes)
return icontent, nil return icontent, nil
} }

View File

@ -6,9 +6,10 @@ import (
"errors" "errors"
"fmt" "fmt"
"html/template" "html/template"
"io/ioutil"
"os" "os"
"path"
"path/filepath" "path/filepath"
"regexp"
"strings" "strings"
) )
@ -16,7 +17,6 @@ var (
beegoTplFuncMap template.FuncMap beegoTplFuncMap template.FuncMap
BeeTemplates map[string]*template.Template BeeTemplates map[string]*template.Template
BeeTemplateExt []string BeeTemplateExt []string
AllTemplateFiles *templatefile
) )
func init() { func init() {
@ -63,7 +63,14 @@ func (self *templatefile) visit(paths string, f os.FileInfo, err error) error {
replace := strings.NewReplacer("\\", "/") replace := strings.NewReplacer("\\", "/")
a := []byte(paths) a := []byte(paths)
a = a[len([]byte(self.root)):] 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 { if _, ok := self.files[subdir]; ok {
self.files[subdir] = append(self.files[subdir], paths) self.files[subdir] = append(self.files[subdir], paths)
} else { } else {
@ -101,19 +108,55 @@ func BuildTemplate(dir string) error {
return errors.New("dir open err") return errors.New("dir open err")
} }
} }
AllTemplateFiles = &templatefile{ self := &templatefile{
root: dir, root: dir,
files: make(map[string][]string), files: make(map[string][]string),
} }
err := filepath.Walk(dir, func(path string, f os.FileInfo, err error) error { 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 { if err != nil {
fmt.Printf("filepath.Walk() returned %v\n", err) fmt.Printf("filepath.Walk() returned %v\n", err)
return 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 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
}