gview模板引擎增加多目录检索功能,gfile包增加源码main包目录获取方法

This commit is contained in:
John
2018-05-03 16:12:01 +08:00
parent ffaebd046a
commit 1e42e73ba3
4 changed files with 65 additions and 29 deletions

View File

@ -9,13 +9,11 @@
package gins
import (
"runtime"
"gitee.com/johng/gf/g/os/gcfg"
"gitee.com/johng/gf/g/os/gcmd"
"gitee.com/johng/gf/g/os/genv"
"gitee.com/johng/gf/g/os/gview"
"gitee.com/johng/gf/g/os/gfile"
"gitee.com/johng/gf/g/util/gregx"
"gitee.com/johng/gf/g/container/gmap"
)
@ -51,6 +49,11 @@ func View() *gview.View {
}
}
view := gview.Get(path)
// 添加代码级的搜索目录检索地址,常用于开发环境调试,只添加入口文件目录
mainDirPath := gfile.MainPkgPath()
if mainDirPath != "" {
view.AddPath(mainDirPath)
}
Set(gFRAME_CORE_COMPONENT_NAME_VIEW, view)
return view
}
@ -73,19 +76,9 @@ func Config() *gcfg.Config {
}
config := gcfg.New(path)
// 添加代码级的搜索目录检索地址,常用于开发环境调试,只添加入口文件目录
path = ""
for i := 1; i < 10000; i++ {
if _, file, _, ok := runtime.Caller(i); ok {
// 不包含go源码路径
if !gregx.IsMatchString("^" + runtime.GOROOT(), file) {
path = file
}
} else {
break
}
}
if path != "" {
config.AddPath(gfile.Dir(path))
mainDirPath := gfile.MainPkgPath()
if mainDirPath != "" {
config.AddPath(mainDirPath)
}
// 单例对象缓存控制
Set(gFRAME_CORE_COMPONENT_NAME_CONFIG, config)

View File

@ -9,7 +9,6 @@ package gfile
import (
"os"
"path/filepath"
"io"
"io/ioutil"
"sort"
@ -21,6 +20,9 @@ import (
"errors"
"os/user"
"runtime"
"path/filepath"
"gitee.com/johng/gf/g/util/gregx"
"gitee.com/johng/gf/g/container/gtype"
)
// 封装了常用的文件操作方法如需更详细的文件控制请查看官方os包
@ -30,6 +32,9 @@ const (
Separator = string(filepath.Separator)
)
// 源码的main包所在目录仅仅会设置一次
var mainPkgPath = gtype.NewInterface()
// 给定文件的绝对路径创建文件
func Mkdir(path string) error {
err := os.MkdirAll(path, os.ModePerm)
@ -432,4 +437,29 @@ func GetBinContentByTwoOffsets(file *os.File, start int64, end int64) []byte {
return nil
}
return buffer
}
// 获取入口函数文件所在目录(main包文件目录),仅对源码开发环境有效(即仅对生成该可执行文件的系统下有效)
func MainPkgPath() string {
path := mainPkgPath.Val()
if path != nil {
return path.(string)
}
f := ""
for i := 1; i < 10000; i++ {
if _, file, _, ok := runtime.Caller(i); ok {
// 不包含go源码路径
if !gregx.IsMatchString("^" + runtime.GOROOT(), file) {
f = file
}
} else {
break
}
}
if f != "" {
p := Dir(f)
mainPkgPath.Set(p)
return p
}
return ""
}

View File

@ -11,20 +11,19 @@ import (
"sync"
"bytes"
"errors"
"strings"
"html/template"
"gitee.com/johng/gf/g/os/gfile"
"gitee.com/johng/gf/g/container/gmap"
"gitee.com/johng/gf/g/container/gtype"
"gitee.com/johng/gf/g/encoding/ghash"
"gitee.com/johng/gf/g/util/gconv"
"gitee.com/johng/gf/g/os/gfsnotify"
"gitee.com/johng/gf/g/os/gspath"
)
// 视图对象
type View struct {
mu sync.RWMutex
path *gtype.String // 模板目录(绝对路径)
paths *gspath.SPath // 模板查找目录(绝对路径)
funcmap map[string]interface{} // FuncMap
contents *gmap.StringStringMap // 已解析的模板文件内容
}
@ -57,8 +56,10 @@ func Get(path string) *View {
// 生成一个视图对象
func New(path string) *View {
s := gspath.New()
s.Set(path)
view := &View {
path : gtype.NewString(path),
paths : s,
funcmap : make(map[string]interface{}),
contents : gmap.NewStringStringMap(),
}
@ -67,32 +68,30 @@ func New(path string) *View {
}
// 设置模板目录绝对路径
func (view *View) SetPath(path string) {
view.path.Set(path)
func (view *View) SetPath(path string) error {
return view.paths.Set(path)
}
// 获取模板目录绝对路径
func (view *View) GetPath() string {
return view.path.Val()
// 添加模板目录搜索路径
func (view *View) AddPath(path string) error {
return view.paths.Add(path)
}
// 解析模板,返回解析后的内容
func (view *View) Parse(file string, params map[string]interface{}) ([]byte, error) {
path := strings.TrimRight(view.GetPath(), gfile.Separator) + gfile.Separator + file
path := view.paths.Search(file)
content := view.contents.Get(path)
if content == "" {
content = gfile.GetContents(path)
if content != "" {
view.mu.Lock()
view.addMonitor(path)
view.contents.Set(path, content)
view.mu.Unlock()
}
}
if content == "" {
return nil, errors.New("tpl \"" + file + "\" not found")
}
// 执行模板解析
// 执行模板解析互斥锁主要是用于funcmap
view.mu.RLock()
defer view.mu.RUnlock()
buffer := bytes.NewBuffer(nil)

14
geg/os/gview/gview.go Normal file
View File

@ -0,0 +1,14 @@
package main
import (
"fmt"
"gitee.com/johng/gf/g"
)
func main() {
v := g.View()
b, err := v.Parse("test.tpl", nil)
fmt.Println(err)
fmt.Println(b)
}