func _getTemplate(t0 *template.Template, root string, subMods [][]string, others ...string) (t *template.Template, err error) { t = t0 for _, m := range subMods { if len(m) == 2 { tpl := t.Lookup(m[1]) if tpl != nil { continue } //first check filename for _, otherFile := range others { if otherFile == m[1] { var subMods1 [][]string t, subMods1, err = getTplDeep(root, otherFile, "", t) if err != nil { logs.Trace("template parse file err:", err) } else if subMods1 != nil && len(subMods1) > 0 { t, err = _getTemplate(t, root, subMods1, others...) } break } } //second check define for _, otherFile := range others { fileAbsPath := filepath.Join(root, otherFile) data, err := ioutil.ReadFile(fileAbsPath) if err != nil { continue } reg := regexp.MustCompile(BConfig.WebConfig.TemplateLeft + "[ ]*define[ ]+\"([^\"]+)\"") allSub := reg.FindAllStringSubmatch(string(data), -1) for _, sub := range allSub { if len(sub) == 2 && sub[1] == m[1] { var subMods1 [][]string t, subMods1, err = getTplDeep(root, otherFile, "", t) if err != nil { logs.Trace("template parse file err:", err) } else if subMods1 != nil && len(subMods1) > 0 { t, err = _getTemplate(t, root, subMods1, others...) } break } } } } } return }
// ExecuteTemplate applies the template with name to the specified data object, // writing the output to wr. // A template will be executed safely in parallel. func ExecuteTemplate(wr io.Writer, name string, data interface{}) error { if BConfig.RunMode == DEV { templatesLock.RLock() defer templatesLock.RUnlock() } if t, ok := beeTemplates[name]; ok { var err error if t.Lookup(name) != nil { err = t.ExecuteTemplate(wr, name, data) } else { err = t.Execute(wr, data) } if err != nil { logs.Trace("template Execute err:", err) } return err } panic("can't find templatefile in the path:" + name) }
// BuildTemplate will build all template files in a directory. // it makes beego can render any template file in view directory. func BuildTemplate(dir string, files ...string) error { if _, err := os.Stat(dir); err != nil { if os.IsNotExist(err) { return nil } return errors.New("dir open err") } self := &templateFile{ root: dir, files: make(map[string][]string), } err := filepath.Walk(dir, func(path string, f os.FileInfo, err error) error { return self.visit(path, f, err) }) if err != nil { fmt.Printf("filepath.Walk() returned %v\n", err) return err } buildAllFiles := len(files) == 0 for _, v := range self.files { for _, file := range v { if buildAllFiles || utils.InSlice(file, files) { templatesLock.Lock() ext := filepath.Ext(file) var t *template.Template if len(ext) == 0 { t, err = getTemplate(self.root, file, v...) } else if fn, ok := beeTemplateEngines[ext[1:]]; ok { t, err = fn(self.root, file, beegoTplFuncMap) } else { t, err = getTemplate(self.root, file, v...) } if err != nil { logs.Trace("parse template err:", file, err) } else { beeTemplates[file] = t } templatesLock.Unlock() } } } return nil }
// Trace logs a message at trace level. // compatibility alias for Warning() func Trace(v ...interface{}) { logs.Trace(generateFmtStr(len(v)), v...) }