diff --git a/g/frame/gins/gins.go b/g/frame/gins/gins.go index b81e9a763..c81ff0625 100644 --- a/g/frame/gins/gins.go +++ b/g/frame/gins/gins.go @@ -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) diff --git a/g/os/gfile/gfile.go b/g/os/gfile/gfile.go index bdbc4a1e0..2ab52d11c 100644 --- a/g/os/gfile/gfile.go +++ b/g/os/gfile/gfile.go @@ -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 "" } \ No newline at end of file diff --git a/g/os/gview/gview.go b/g/os/gview/gview.go index ecf6f3f53..70562992e 100644 --- a/g/os/gview/gview.go +++ b/g/os/gview/gview.go @@ -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) diff --git a/geg/os/gview/gview.go b/geg/os/gview/gview.go new file mode 100644 index 000000000..5149af00d --- /dev/null +++ b/geg/os/gview/gview.go @@ -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) +} \ No newline at end of file