2016-12-16 72 views
9

html/template(和text/template)封裝,template.New具有以下特徵:轉到模板名稱

func New(name string) *Template 

究竟是用來做什麼的name?我掃描了文檔(和一些源文件),但無濟於事。我只是用空字符串來實例化所有的模板,但它似乎沒有什麼區別。我爲什麼要打擾一個名字?

即使命名模板,兩人似乎等價的:

template.Must(template.New("").Parse(`{{ define "body" }}Body{{ end }}`)) 
template.Must(template.New("body").Parse(`Body`)) 

https://play.golang.org/p/wKzCHdLf2S

回答

10

模板的名稱 - 令人驚訝的是 - 名稱模板。

這有什麼好處?只要你不想參考到模板,它並不重要。但是如果你想參考它,那麼是的,你可以通過它的名稱來引用它。

什麼時候你想參考它?當您想要在另一個例如使用{{template}}操作,或者當您想要使用Template.ExecuteTemplate()執行特定模板時。

目前爲止還不錯,但仍然缺少一個關鍵點。這不是明確/微不足道的:template.Template值是「解析模板的表示」。但這裏的措辭有點「不完美」。一個template.Template的值可以是(並且通常是)多個關聯模板集合template.Template有一個未導出字段:

tmpl map[string]*Template // Map from name to defined templates. 

tmpl字段保存的所有其他相關的方案,這是對模板可見的模板,並且可以被稱爲通過其到-YES-。

當你解析多個一次模板,使用Template.ParseFiles()Template.ParseGlob(),那麼模板將通過文件名命名的,它們將被自動關聯(上述函數返回一個template.Template值,它包含所有解析的模板,關聯)。Template.ParseFiles()的文檔清楚如下:

ParseFiles創建一個新的模板並分析來自命名文件的模板定義。返回的模板名稱將具有第一個文件的基本名稱和解析內容。 [...]

當在不同目錄中解析具有相同名稱的多個文件時,最後提到的那個文件將會是結果。例如,ParseFiles(「a/foo」,「b/foo」)存儲「b/foo」作爲名爲「foo」的模板,而「a/foo」不可用。

模板名稱來自多個地方

  • 它可以來自文件名(如上所示)
  • 可以明確指定(如果使用定義的{{define "somename"}}{{block "somename"}} actions),
  • 或者它可以被定義爲傳遞給template.New()(函數)或Template.New()(方法)的參數

讓我們看一些例子:

func main() { 
    t := template.Must(template.New("one").Parse(t1src)) 
    template.Must(t.New("other").Parse(t2src)) 

    // error checks omitted for brevity 
    // Executes default, "one": 
    t.Execute(os.Stdout, nil) 

    // Executes explicit, "one": 
    t.ExecuteTemplate(os.Stdout, "one", nil) 

    // Executes explicit, "other": 
    t.ExecuteTemplate(os.Stdout, "other", nil) 
} 

const t1src = `I'm some template. 
` 
const t2src = `I'm some OTHER template. 
` 

輸出(嘗試在Go Playground):

I'm some template. 
I'm some template. 
I'm some OTHER template. 

如果你現在去進取,改變前兩行這樣的:

t := template.Must(template.New("one").Parse(t1src)) 
t = template.Must(t.New("other").Parse(t2src)) 

然後這裏發生的是,我們assi將新的template.Template值設置爲t,這是解析t2src的結果,因此這將是默認值,但仍然可以在它們關聯時從這兩個模板中「達到」這兩個模板。輸出修改本(嘗試在Go Playground):

I'm some OTHER template. 
I'm some template. 
I'm some OTHER template. 

調用template.New()(功能)創建一個新的模板,關聯到無。當調用Template.New()(方法)時,返回的模板將與調用該方法的(全部)模板相關聯。

現在讓我們看一些關於「嵌入」模板的例子。

func main() { 
    t := template.Must(template.New("one").Parse(t1src)) 
    template.Must(t.New("other").Parse(t2src)) 
    template.Must(t.New("third").Parse(t3src)) 

    t.Execute(os.Stdout, nil) 
    t.ExecuteTemplate(os.Stdout, "one", nil) 
    t.ExecuteTemplate(os.Stdout, "other", nil) 
    t.ExecuteTemplate(os.Stdout, "embedded", nil) 
    t.ExecuteTemplate(os.Stdout, "third", nil) 
} 

const t1src = `I'm some template. {{block "embedded" .}}I'm embedded in "one". 
{{end}}` 
const t2src = `I'm some OTHER template. 
` 
const t3src = `I'm the 3rd, including everything from "one": {{template "one"}} 
` 

輸出(嘗試在Go Playground):

I'm some template. I'm embedded in "one". 
I'm some template. I'm embedded in "one". 
I'm some OTHER template. 
I'm embedded in "one". 
I'm the 3rd, including everything from "one": I'm some template. I'm embedded in "one". 

它現在應該是顯而易見的模板名稱的角色是什麼,以及它來自哪裏。

4

它是用來渲染的相關模板。

例如:

tmpl := template.Must(template.New("body").Parse(` 
    {{ define "body" }} 
     Body 
    {{ end }} 
    `)) 

tmpl = template.Must(tmpl.New("base").Parse(` 
    Start of base template 

    {{ template "body" }} 

    End of base template 
    `)) 

tmpl = template.Must(tmpl.New("baz").Parse(` 
    Start of baz template 

    {{ template "body" }} 

    End of baz template 
    `)) 

tmpl.ExecuteTemplate(os.Stdout, "base", nil) 
tmpl.ExecuteTemplate(os.Stdout, "baz", nil) 

Play Example

輸出:

 Start of base template 


     Body 


    End of base template 

    Start of baz template 


     Body 


    End of baz template 

tmpl.ExecuteTemplate(os.Stdout, "base", nil)將使用 「基地」 模板

tmpl.ExecuteTemplate(os.Stdout, "baz", nil)將使用呈現模板呈現模板「b az「模板

+0

除了如果我將第一行更改爲'template.New(「」)',那麼它的工作原理也是如此。 https://play.golang.org/p/zQoGalIxFq 但我認爲你在做某件事。沒有命名「基本」模板,ExecuteTemplate似乎不起作用。 – Dave

+0

下面是同樣的例子,但是所有模板名稱均爲空字符串。 https://play.golang.org/p/0NdJ1j_ype它看起來像'{{define'name「}}'可以替代'New'方法中的模板。 – Dave

+0

@Dave我添加了第三個模板以更好地說明命名模板的實用程序。 – jmaloney