使用方法

通用视图管理

通用视图管理即使用原生的模板引擎gview模块来实现模板管理,包括模板读取展示,模板变量渲染等等,可以通过对象管理器g.View()来获取默认的单例gview对象。

方法列表:

  1. func HTML(content string) template.HTML
  2. func ParseContent(content string, params map[string]interface{}) ([]byte, error)
  3. type View
  4. func Get(path string) *View
  5. func New(path string) *View
  6. func (view *View) AddPath(path string) error
  7. func (view *View) SetPath(path string) error
  8. func (view *View) Assign(key string, value interface{})
  9. func (view *View) Assigns(data Params)
  10. func (view *View) BindFunc(name string, function interface{})
  11. func (view *View) Parse(file string, params map[string]interface{}, funcmap ...map[string]interface{}) ([]byte, error)
  12. func (view *View) ParseContent(content string, params map[string]interface{}, funcmap ...map[string]interface{}) ([]byte, error)
  13. func (view *View) SetDelimiters(left, right string)

简要说明:

  1. gview.Get用于根据给定的一个模板目录路径,获得对应的单例模板引擎对象;
  2. gview.New同样可以根据给定的模板目录路径创建模板引擎对象,但没有单例管理;
  3. SetPath/AddPath用于设置/添加当前模板引擎对象的模板目录路径,其中SetPath会覆盖所有的模板目录设置,推荐使用AddPath
  4. Assign/Assigns用于设置模板变量,通过该模板引擎解析的所有模板均可以使用这些模板变量;
  5. BindFunc用于绑定模板函数,具体使用方法参考后续示例程序;
  6. Parse/ParseContent用于解析模板文件/内容,可以在解析时给定临时的模板变量及模板函数;
  7. SetDelimiters用于设置该模板引擎对象的模板解析分隔符号,默认为{{ }}(与vuejs前端框架有冲突);

示例1,解析模板文件

  1. package main
  2. import (
  3. "gitee.com/johng/gf/g/net/ghttp"
  4. "gitee.com/johng/gf/g/frame/gins"
  5. )
  6. func main() {
  7. s := ghttp.GetServer()
  8. s.BindHandler("/template2", func(r *ghttp.Request){
  9. content, _ := gins.View().Parse("index.tpl", map[string]interface{}{
  10. "id" : 123,
  11. "name" : "john",
  12. })
  13. r.Response.Write(content)
  14. })
  15. s.SetPort(8199)
  16. s.Run()
  17. }

在这个示例中我们使用单例管理器获取一个默认的视图对象,随后通过该视图渲染对应模板目录下的index.tpl模板文件并给定模板变量参数。

我们也可以通过SetPath/Addpath方法中心指定视图对象的模板目录,该方法是并发安全的,但是需要注意一旦改变了该视图对象的模板目录,将会在整个进程中生效。当然,也可以直接解析模板内容。

示例2,解析模板内容

  1. package main
  2. import (
  3. "gitee.com/johng/gf/g/net/ghttp"
  4. "gitee.com/johng/gf/g/frame/gins"
  5. )
  6. func main() {
  7. s := ghttp.GetServer()
  8. s.BindHandler("/template2", func(r *ghttp.Request){
  9. tplcontent := `id:{{.id}}, name:{{.name}}`
  10. content, _ := gins.View().ParseContent(tplcontent, map[string]interface{}{
  11. "id" : 123,
  12. "name" : "john",
  13. })
  14. r.Response.Write(content)
  15. })
  16. s.SetPort(8199)
  17. s.Run()
  18. }

执行后,访问http://127.0.0.1:8199/template2可以看到解析后的内容为:id:123, name:john

示例3,自定义模板变量分隔符

在项目中我们经常会遇到Golang默认模板变量分隔符号与Vue的变量分隔符号冲突的情况(都使用的是{{ }}),我们可以使用SetDelimiters方法来自定义全局的Golang模板变量分隔符号:

  1. // main.go
  2. package main
  3. import (
  4. "fmt"
  5. "gitee.com/johng/gf/g"
  6. )
  7. func main() {
  8. v := g.View()
  9. v.SetDelimiters("${", "}")
  10. b, err := v.Parse("gview_delimiters.tpl", map[string]interface{} {
  11. "k" : "v",
  12. })
  13. fmt.Println(err)
  14. fmt.Println(string(b))
  15. }
  1. <!-- gview_delimiters.tpl -->
  2. test.tpl content, vars: ${.}

执行后,输出结果为:

  1. <nil>
  2. test.tpl content, vars: map[k:v]

控制器视图管理

gf为控制器提供了良好的模板引擎支持,由gmvc.View视图对象进行管理,提供了良好的数据隔离性。控制器视图是并发安全设计的,允许在多线程中异步操作。

  1. func (view *View) Assign(key string, value interface{})
  2. func (view *View) Assigns(data gview.Params)
  3. func (view *View) Parse(file string) ([]byte, error)
  4. func (view *View) ParseContent(content string) ([]byte, error)
  5. func (view *View) Display(files ...string) error
  6. func (view *View) DisplayContent(content string) error
  7. func (view *View) LockFunc(f func(vars map[string]interface{}))
  8. func (view *View) RLockFunc(f func(vars map[string]interface{}))

使用示例1:

  1. package main
  2. import (
  3. "gitee.com/johng/gf/g/net/ghttp"
  4. "gitee.com/johng/gf/g/frame/gmvc"
  5. )
  6. type ControllerTemplate struct {
  7. gmvc.Controller
  8. }
  9. func (c *ControllerTemplate) Info() {
  10. c.View.Assign("name", "john")
  11. c.View.Assigns(map[string]interface{}{
  12. "age" : 18,
  13. "score" : 100,
  14. })
  15. c.View.Display("index.tpl")
  16. }
  17. func main() {
  18. s := ghttp.GetServer()
  19. s.BindController("/template", new(ControllerTemplate{}))
  20. s.SetPort(8199)
  21. s.Run()
  22. }

其中index.tpl的模板内容如下:

  1. <html>
  2. <head>
  3. <title>gf template engine</title>
  4. </head>
  5. <body>
  6. <p>Name: {{.name}}</p>
  7. <p>Age: {{.age}}</p>
  8. <p>Score:{{.score}}</p>
  9. </body>
  10. </html>

执行后,访问http://127.0.0.1:8199/template/info可以看到模板被解析并展示到页面上。如果页面报错找不到模板文件,没有关系,因为这里并没有对模板目录做设置,默认是当前可行文件的执行目录(Linux&Mac下是/tmp目录,Windows下是C:\Documents and Settings\用户名\Local Settings\Temp)。如何手动设置模板文件目录请查看后续章节,随后可回过头来手动修改目录后看到结果。

其中,给定的模板文件file参数是需要带完整的文件名后缀,例如:index.tplindex.html等等,模板引擎对模板文件后缀名没有要求,用户可完全自定义。此外,模板文件参数也支持文件的绝对路径(完整的文件路径)。

当然,我们也可以直接解析模板内容,请看示例2:

  1. package main
  2. import (
  3. "gitee.com/johng/gf/g/net/ghttp"
  4. "gitee.com/johng/gf/g/frame/gmvc"
  5. )
  6. type ControllerTemplate struct {
  7. gmvc.Controller
  8. }
  9. func (c *ControllerTemplate) Info() {
  10. c.View.Assign("name", "john")
  11. c.View.Assigns(map[string]interface{}{
  12. "age" : 18,
  13. "score" : 100,
  14. })
  15. c.View.DisplayContent(`
  16. <html>
  17. <head>
  18. <title>gf template engine</title>
  19. </head>
  20. <body>
  21. <p>Name: {{.name}}</p>
  22. <p>Age: {{.age}}</p>
  23. <p>Score:{{.score}}</p>
  24. </body>
  25. </html>
  26. `)
  27. }
  28. func main() {
  29. s := ghttp.GetServer()
  30. s.BindController("/template", new(ControllerTemplate{}))
  31. s.SetPort(8199)
  32. s.Run()
  33. }

执行后,访问http://127.0.0.1:8199/template/info可以看到解析后的内容如下:

  1. <html>
  2. <head>
  3. <title>gf template engine</title>
  4. </head>
  5. <body>
  6. <p>Name: john</p>
  7. <p>Age: 18</p>
  8. <p>Score:100</p>
  9. </body>
  10. </html>

修改模板目录

gf框架的模板引擎支持两种方式的模板目录修改。

修改模板目录

模板引擎作为gf框架的核心组件,可以通过以下方式修改模板引擎的默认模板文件查找目录:

  1. (推荐)单例模式获取全局View对象,通过SetPath方法手动修改;
  2. 修改命令行启动参数 - gf.viewpath
  3. 修改指定的环境变量 - gf.viewpath

例如,我们的执行程序文件为main,那么可以通过以下方式修改模板引擎的模板目录(Linux下):

  1. (推荐)通过单例模式
    1. gins.View().SetPath("/opt/template")
  2. 通过命令行参数
    1. ./main --gf.viewpath=/opt/template/
  3. 通过环境变量
    • 启动时修改环境变量:
      1. gf.viewpath=/opt/config/; ./main
    • 使用genv包来修改环境变量:
      1. genv.Set("gf.viewpath", "/opt/template")

添加搜索目录

gf框架的模板引擎支持非常灵活的多目录自动搜索功能,通过SetPath可以修改模板目录为唯一的一个目录地址,同时,我们可以通过AddPath方法添加多个搜索目录(推荐),模板引擎底层将会按照添加目录的顺序作为优先级进行自动检索。直到检索到一个匹配的文件路径为止,如果在所有搜索目录下查找不到模板文件,那么会返回失败。

当我们使用对象管理器g.View()获取模板引擎单例对象时,框架会自动添加两个模板引擎搜索目录:

  • 当前可执行文件的目录;
  • 源代码main包文件目录(仅对源码开发环境有效);

自动检测更新

模板引擎使用了缓存机制,当模板文件第一次被读取后会被缓存到内存,下一次读取时将会直接从缓存中获取,以提高执行效率。并且,模板引擎提供了对模板文件的自动检测更新机制,当模板文件在外部被修改后,模板引擎能够即时地监控到并刷新模板文件的缓存内容。

模板引擎的自动检测更新机制是gf框架特有的一大特色。