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/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
}

View File

@ -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
}