gf框架之模板引擎 – 基本用法

John發表於2018-04-18

文章來源:http://gf.johng.cn/591642

控制器檢視

gf為控制器提供了良好的模板引擎支援,由gmvc.View檢視物件進行管理,提供了良好的資料隔離性。控制器檢視是併發安全設計的,允許在多執行緒中非同步操作。

func (view *View) Assign(key string, value interface{})
func (view *View) Assigns(data map[string]interface{})

func (view *View) Parse(file string) ([]byte, error)
func (view *View) ParseContent(content string) ([]byte, error)

func (view *View) Display(files ...string) error
func (view *View) DisplayContent(content string) error

func (view *View) LockFunc(f func(vars map[string]interface{}))
func (view *View) RLockFunc(f func(vars map[string]interface{}))

使用示例1:

package main

import (
    "gitee.com/johng/gf/g/net/ghttp"
    "gitee.com/johng/gf/g/frame/gmvc"
)

type ControllerTemplate struct {
    gmvc.Controller
}

func (c *ControllerTemplate) Info() {
    c.View.Assign("name", "john")
    c.View.Assigns(map[string]interface{}{
        "age"   : 18,
        "score" : 100,
    })
    c.View.Display("index.tpl")
}

func main() {
    s := ghttp.GetServer()
    s.BindController("/template", &ControllerTemplate{})
    s.SetPort(8199)
    s.Run()
}

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

<html>
    <head>
        <title>gf template engine</title>
    </head>
    <body>
        <p>Name: {{.name}}</p>
        <p>Age:  {{.age}}</p>
        <p>Score:{{.score}}</p>
    </body>
</html>

執行後,訪問http://127.0.0.1:8199/template/info可以看到模板被解析並展示到頁面上。如果頁面報錯找不到模板檔案,沒有關係,因為這裡並沒有對模板目錄做設定,預設是當前可行檔案的執行目錄(Linux&Mac下是/tmp目錄,Windows下是C:Documents and Settings使用者名稱Local SettingsTemp )。如何手動設定模板檔案目錄請檢視後續章節,隨後可回過頭來手動修改目錄後看到結果。

其中,給定的模板檔案file引數是需要帶完整的檔名字尾,例如:index.tplindex.html等等,模板引擎對模板檔案字尾名沒有要求,使用者可完全自定義。此外,模板檔案引數也支援檔案的絕對路徑(完整的檔案路徑)。

當然,我們也可以直接解析模板內容,請看示例2:

package main

import (
    "gitee.com/johng/gf/g/net/ghttp"
    "gitee.com/johng/gf/g/frame/gmvc"
)

type ControllerTemplate struct {
    gmvc.Controller
}

func (c *ControllerTemplate) Info() {
    c.View.Assign("name", "john")
    c.View.Assigns(map[string]interface{}{
        "age"   : 18,
        "score" : 100,
    })
    c.View.DisplayContent(`
        <html>
            <head>
                <title>gf template engine</title>
            </head>
            <body>
                <p>Name: {{.name}}</p>
                <p>Age:  {{.age}}</p>
                <p>Score:{{.score}}</p>
            </body>
        </html>
    `)
}

func main() {
    s := ghttp.GetServer()
    s.BindController("/template", &ControllerTemplate{})
    s.SetPort(8199)
    s.Run()
}

執行後,訪問http://127.0.0.1:8199/template/info可以看到解析後的內容如下:

<html>
    <head>
        <title>gf template engine</title>
    </head>
    <body>
        <p>Name: john</p>
        <p>Age:  18</p>
        <p>Score:100</p>
    </body>
</html>

非控制器檢視

非控制器中使用模板引擎沒有控制器檢視的支援,可以使用底層的gview包來實現,可以通過單例管理器來獲取預設的單例gview物件。

gview包方法列表:

func Get(path string) *View
func New(path string) *View
func (view *View) BindFunc(name string, function interface{})
func (view *View) Parse(file string, params map[string]interface{}) ([]byte, error)
func (view *View) ParseContent(content string, params map[string]interface{}) ([]byte, error)

func (view *View) GetPath() string
func (view *View) SetPath(path string)

使用示例1:

package main

import (
    "gitee.com/johng/gf/g/net/ghttp"
    "gitee.com/johng/gf/g/frame/gins"
)

func main() {
    s := ghttp.GetServer()
    s.BindHandler("/template2", func(r *ghttp.Request){
        content, _ := gins.View().Parse("index.tpl", map[string]interface{}{
            "id"   : 123,
            "name" : "john",
        })
        r.Response.Write(content)
    })
    s.SetPort(8199)
    s.Run()
}

在這個示例中我們使用單例管理器獲取一個預設的檢視物件,隨後通過該檢視渲染對應模板目錄下的index.tpl模板檔案並給定模板變數引數。

我們也可以通過SetPath方法中心指定檢視物件的模板目錄,該方法是併發安全的,但是需要注意一旦改變了該檢視物件的模板目錄,將會在整個程式中生效。

當然,也可以直接解析模板內容,使用示例2:

package main

import (
    "gitee.com/johng/gf/g/net/ghttp"
    "gitee.com/johng/gf/g/frame/gins"
)

func main() {
    s := ghttp.GetServer()
    s.BindHandler("/template2", func(r *ghttp.Request){
        tplcontent := `id:{{.id}}, name:{{.name}}`
        content, _ := gins.View().ParseContent(tplcontent, map[string]interface{}{
            "id"   : 123,
            "name" : "john",
        })
        r.Response.Write(content)
    })
    s.SetPort(8199)
    s.Run()
}

執行後,訪問http://127.0.0.1:8199/template2可以看到解析後的內容為:id:123, name:john

此外,需要注意的是,雖然以上示例都是在Web Server中進行展示的,但是模板引擎是對模板檔案/內容的智慧解析,可以用在任何的場景中。

修改模板目錄

模板引擎作為gf框架的核心元件,可以通過以下方式修改模板引擎的預設模板檔案查詢目錄:

  1. (推薦)單例模式獲取全域性View物件,通過SetPath方法手動修改
  2. 修改命令列啟動引數 – viewpath
  3. 修改指定的環境變數 – gf.viewpath

例如,我們的執行程式檔案為main,那麼可以通過以下方式修改模板引擎的模板目錄(Linux下):

  1. (推薦)通過單例模式

    gins.View().SetPath("/opt/template")
  2. 通過命令列引數

    ./main --viewpath=/opt/template/
  3. 通過環境變數

    • 啟動時修改環境變數:

      gf.viewpath=/opt/config/; ./main
    • 使用genv包來修改環境變數:

      genv.Set("gf.viewpath", "/opt/template")

自動檢測更新

模板引擎使用了快取機制,當模板檔案第一次被讀取後會被快取到記憶體,下一次讀取時將會直接從快取中獲取,以提高執行效率。並且,模板引擎提供了對模板檔案的自動檢測更新機制,當模板檔案在外部被修改後,模板引擎能夠即時地監控到並重新整理模板檔案的快取內容。

模板引擎的自動檢測更新機制也是gf框架的一大特色。

相關文章