去模板名称 [英] Go template name

查看:92
本文介绍了去模板名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

html / template (和 text / template )包中, template.New 具有以下签名:

  func New(name string)* Template 

name 用于什么?我扫描了文档(和一些源文件),但无济于事。我只是用空字符串来实例化所有的模板,这似乎没有什么区别。为什么要打扰一个名字?



即使对于命名模板,这两个看起来也是相同的:

  template.Must(template.New()。Parse(`{{definebody}} Body {{end}}`))
template.Must(template.New (body)。Parse(`Body`))

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

解决方案

模板的名称 - 令人惊讶 - 模板的名称。



这有什么好处?只要您不希望将引用到模板,它并不重要。但是,如果你想 来引用,那么是的,你可以通过它的名字来引用它。

当你想参考它吗?当您想要在另一个例如使用 {{template}} 动作,或者当您想要使用 Template.ExecuteTemplate()

迄今为止很好,但仍有一个缺失的关键点。这不是明确/微不足道的: template.Template 值是解析模板的表示形式。但这里的措辞有点不完美。 template.Template 值可能(通常是)多个关联模板的集合 template.Template 有一个未导出的字段:

  tmpl map [string] *模板//从名称映射到定义的模板。 

这个 tmpl 字段包含所有其他相关模板,模板可见的模板以及可以通过它们的名称引用的



当您解析一次使用 Template.ParseFiles() Template.ParseGlob () ,那么模板将以文件名命名,并且它们将自动关联(上述函数返回一个 template.Template code> value,它包含所有已解析的模板)。文件 Template.ParseFiles()在此明确表示:


ParseFiles创建一个新的模板并分析来自命名文件的模板定义。返回的模板名称将具有第一个文件的基本名称和解析内容。 [b]

在不同目录中解析多个具有相同名称的文件时,最后一个将会是结果。例如,ParseFiles(a / foo,b / foo)存储b / foo作为名为foo的模板,而a / foo不可用。


< blockquote>

模板名称可以来自多个位置


  • 它可以来自文件名(如上所示)。
  • 可以明确指定它(如果使用 {{definesomename}} code>或 {{blocksomename}} actions),

  • 或者它可以被定义为传递给 template.New() (功能)或 Template.New( ) (method)
  • p>

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

    // err或者为了简洁省略检查
    //执行默认值,one:
    t.Execute(os.Stdout,nil)

    //执行显式的one:
    t.ExecuteTemplate(os.Stdout,one,nil)

    //执行显式的other:
    t.ExecuteTemplate(os.Stdout,other,无)
    }

    const t1src =`我是一些模板。
    `
    const t2src =`我是OTHER模板。
    `

    输出(尝试在 Go Playground ):

      m一些模板。 
    我是一些模板。
    我是其他一些模板。

    如果现在继续,请将前两行更改为:

      t:= template.Must(template.New(one)。Parse(t1src))
    t = template.Must(t。新(其他)。解析(t2src))

    然后在这里发生的是,新的 template.Template 值改为 t ,这是解析 t2src ,所以这将是默认值,但仍然可以在它们相关联时从它们达到两个模板。输出变成这样(在 Go Playground 上试试):

     我是OTHER OTHER模板。 
    我是一些模板。
    我是其他一些模板。

    调用 template.New()(function )创建一个新的模板,并且与之相关联。当调用 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 =`我是一些模板。 {{blockembedded。}}我被嵌入到one中。
    {{end}}`
    const t2src =`我是OTHER模板。
    `
    const t3src =`我是第三,包括one的所有内容:{{templateone}}
    `

    输出(在上试用Go Playground ):

     我是一些模板。我嵌入一。 
    我是一些模板。我嵌入一。
    我是其他一些模板。
    我嵌入了one。
    我是第三名,包括one的所有内容:我是一些模板。我嵌入一。

    现在显而易见的是模板名称的作用以及来自哪里。


    In the html/template (and text/template) packages, template.New has the following signature:

    func New(name string) *Template
    

    What exactly is the name used for? I've scanned the docs (and a bit of source), but to no avail. I just instantiate all of my templates with an empty string and it doesn't seem to make a difference. Why should I bother with a name?

    Even for naming templates, the two seem equivalent:

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

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

    解决方案

    The name of the template –unsurprisingly– is to name the template.

    What is it good for? As long as you don't want to refer to the template, it doesn't really matter. But if you want to refer to it, then yes, you refer to it by its name.

    When would you want to refer to it? When you want to include a template in another e.g. using the {{template}} action, or when you want to execute a specific template using Template.ExecuteTemplate().

    So far so good, but there's still a missing key point. This is not unambiguous / trivial: a template.Template value is "the representation of a parsed template". But the wording here is a little "imperfect". A template.Template value may be (and usually is) a collection of multiple, associated templates. template.Template has an unexported field:

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

    This tmpl field holds all other associated templates, templates that are visible to the template, and which can be referred to –yes– by their names.

    When you parse multiple templates at once, using Template.ParseFiles() or Template.ParseGlob(), then the templates will be named by the file names, and they will be associated automatically (the above mentioned functions return a single template.Template value, which holds all the parsed templates, associated). Doc of Template.ParseFiles() is clear on this:

    ParseFiles creates a new Template and parses the template definitions from the named files. The returned template's name will have the base name and parsed contents of the first file. [...]

    When parsing multiple files with the same name in different directories, the last one mentioned will be the one that results. For instance, ParseFiles("a/foo", "b/foo") stores "b/foo" as the template named "foo", while "a/foo" is unavailable.

    The template name can come from multiple places:

    • it can come from the file name (as seen above)
    • it can be specified explicitly (if defined using the {{define "somename"}} or {{block "somename"}} actions),
    • or it may be defined as an argument passed to template.New() (function) or Template.New() (method).

    Let's see some examples:

    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.
    `
    

    Output (try it on the Go Playground):

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

    If you now go ahead, and change the first 2 lines to this:

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

    Then what happens here is that we assigned a new template.Template value to t, which was the result of parsing t2src, so that will be the default, but still both templates can be "reached" from it as they are associated. The output changes to this (try it on the Go Playground):

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

    Calling template.New() (function) creates a new template, associated to none. When calling Template.New() (method), the returned template will be associated with (all) the template(s) the method is called on.

    Now let's see some examples regarding "embedded" templates.

    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"}}
    `
    

    Output (try it on the 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".
    

    It should be obvious now what the role of the template name is, and where it comes from.

    这篇关于去模板名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆