[Go] Beego 模板嵌套 使用總結

經過如下文章,掌握了 Go 模板引擎 的基本用法:php

但在開始學習 Beego 框架的 模板嵌套 模塊源碼時,有點似懂非懂的感受。認真研究了一段時間,總算搞懂了 其本質的原理:html

一、Beego 底層用的是 Go 自帶的模板引擎,所以,只須要繼續研究 Go 自帶的 模板嵌套 的使用方法便可;mvc

二、主要涉及到 4 個模板方法:New()Parse()Lookup()Execute(),先看幾個例子:框架

示例1:

tpl, _ := template.New("mod1").Parse(`我是mod1`)
tpl, _ = tpl.New("mod2").Parse(`我是mod2`)
tpl, _ = tpl.New("mod3").Parse(`我是mod3`)

tpl.Execute(os.Stdout, nil)
fmt.Println("\n++++++++++++++++")
fmt.Println(tpl.Name())

輸出:學習

我是mod3
++++++++++++++++
mod3

示例2:

tpl, _ := template.New("mod1").Parse(`我是mod1`)
tpl, _ = tpl.New("mod2").Parse(`我是mod2`)
tpl, _ = tpl.New("mod3").Parse(`我是mod3`)

tpl2 := tpl.Lookup("mod2")

if tpl2 != nil {
    tpl2.Execute(os.Stdout, nil)
}

輸出:spa

我是mod2

示例3:

tpl, _ := template.New("mod1").Parse(`我是mod1`)
tpl, _ = tpl.New("mod2").Parse(`{{define "Title"}}我是mod2_標題{{end}}我是mod2_內容`)
tpl, _ = tpl.New("mod3").Parse(`我是mod3`)

tpl2 := tpl.Lookup("mod2")

if tpl2 != nil {
    tpl2.Execute(os.Stdout, nil)
}

輸出:htm

我是mod2_內容

示例4:

tpl, _ := template.New("mod1").Parse(`我是mod1`)
tpl, _ = tpl.New("mod2").Parse(`{{define "Title"}}我是mod2_標題{{end}}我是mod2_內容`)
tpl, _ = tpl.New("mod3").Parse(`我是mod3`)

tpl2 := tpl.Lookup("Title")

if tpl2 != nil {
    tpl2.Execute(os.Stdout, nil)
}

輸出:對象

我是mod2_標題

示例5:

tpl, _ := template.New("mod1").Parse(`我是mod1`)
tpl, _ = tpl.New("mod2").Parse(`{{define "Title"}}我是mod2_標題{{end}}我是mod2_內容`)
tpl, _ = tpl.New("mod3").Parse(`我是mod3`)
tpl = tpl.New("mod4")
tpl, _ = tpl.New("mod5").Parse("我是mod5")

fmt.Println(tpl.Name())
fmt.Println("+++++++++++++++")

tpl2 := tpl.Lookup("mod4")
if tpl2 != nil {
    tpl2.Execute(os.Stdout, nil)
}

tpl3 := tpl.Lookup("mod5")
if tpl3 != nil {
    tpl3.Execute(os.Stdout, nil)
}

輸出:blog

mod5
+++++++++++++++
我是mod5

示例6:

tpl, _ := template.New("mod1").Parse(`我是mod1`)
tpl, _ = tpl.New("mod2").Parse(`{{define "Title"}}我是mod2_標題{{end}}我是mod2_內容`)

tpl, _ = tpl.New("mod1").Parse(`我是mod1_內容{{define "Title"}}我是mod1_標題{{end}}`)

fmt.Println(tpl.Name())
fmt.Println("+++++++++++++++")

tpl2 := tpl.Lookup("mod1")
if tpl2 != nil {
    tpl2.Execute(os.Stdout, nil)
}

fmt.Println("\n+++++++++++++++")

tpl3 := tpl.Lookup("Title")
if tpl3 != nil {
    tpl3.Execute(os.Stdout, nil)
}

輸出:模板引擎

mod1
+++++++++++++++
我是mod1_內容
+++++++++++++++
我是mod1_標題

示例7:

tpl, _ := template.New("mod1").Parse(`我是mod1`)
tpl, _ = tpl.New("mod2").Parse(`{{define "Title"}}我是mod2_標題{{end}}我是mod2_內容`)
tpl, _ = tpl.New("mod3").Parse(`我是mod3_{{template "mod1"}}_{{template "Title"}}`)

tpl2 := tpl.Lookup("mod3")

if tpl2 != nil {
    tpl2.Execute(os.Stdout, nil)
}

輸出:

我是mod3_我是mod1_我是mod2_標題

總結:

一、一個模板對象,能夠有多個「名稱」,可是經過 .Name() 方法,只返回最後一次經過 .New() 方法新建的「名稱」。特別注意:此時的 模板對象 的 數據段也是指向該「名稱」所綁定的「字符串」數據;

二、一個模板對象,能夠有多個「名稱」,可是他們是相互獨立的,每一個「名稱」,經過 .Parse() 方法,能夠與一段「字符串」數據對象創建關聯。也就是說,後期經過 .Lookup("某個名稱") 方法獲取到的(模板)對象,其當前數據段,指向該「字符串」,再經過 .Execute() 方法輸出的內容,也是跟該「字符串」相關的內容;

三、在某個「名稱」的數據「字符串」對象中,能夠用 define 定義子模塊名,如 {{define "子模塊名"}}子模塊內容{{end}},該 「子模塊」又獨立於 當前「名稱」,即 當前「名稱」的輸出內容,不包含 「子模板」的內容,參考 示例3

只輸出「我是mod2_內容」,並無輸出「我是mod2_標題

四、特別注意,經過 {{define "子模塊名"}}子模塊內容{{end}} 定義的名稱,並非 模板對象 的一個「名稱」,可是咱們一樣能夠用  .Lookup("某個名稱") 方法獲取到對象,其當前數據段,指向該 「子模塊」,再經過 .Execute() 方法輸出的內容,也是跟該「子模塊」相關的內容,查看 示例4

只輸出「我是mod2_標題

五、可用重複定義「名稱」和 「子模塊」,但後面定義的會覆蓋前面定義的,即 只有最後一次定義的有效。參考 示例6

六、模板內容(「名稱」的「字符串」對象)中,可經過 template 關鍵字來 引用/包含 「名稱」和 「子模塊」,如 {{template "名稱/子模塊"}},參考 示例7

 

搞明白了這些基礎知識,再回過頭看 Beego 的模板模塊,已經是很是簡單了!

相關文章
相關標籤/搜索