当前位置: 首页 > 面试题库 >

转到模板名称

娄鹤轩
2023-03-14
问题内容

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


问题答案:

毫无疑问,模板的名称就是为模板 命名

到底有什么好处呢?只要您不想 引用 该模板,就没有关系。但是,如果要 引用 它,那么可以,您可以通过它的 名称 来引用它。

您什么时候要参考?当您想要将模板包含在另一个模板中时(例如,使用{{template}}操作),或者您想使用执行特定模板Template.ExecuteTemplate()

到目前为止,一切都很好,但是仍然缺少关键点。这不是明确/琐碎的:template.Template值是
“已解析模板的表示形式” 。但是这里的措辞有点“不完善”。甲template.Template值可以是(并且通常是) 的倍数,相关联的模板的集合
template.Template具有未导出的字段:

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

tmpl字段包含所有其他关联的模板,这些模板对于模板可见,并且可以通过其 名称 来指代(是)。

当您使用或一次解析 多个 模板时,这些模板将以文件名命名,并且它们将自动关联(上述函数返回一个值,该值包含所有关联的已解析模板)。Doc
对此很清楚:Template.ParseFiles()Template.ParseGlob()template.Template``Template.ParseFiles()

ParseFiles创建一个新的模板,并从命名文件中解析模板定义。返回的模板名称将具有第一个文件的基本名称和已解析的内容。[…]

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

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

  • 它可以来自文件名(如上所示)
  • 可以明确指定(如果使用{{define "somename"}}{{block "somename"}}动作定义),
  • 或者可以将其定义为传递给template.New()(function)或Template.New()(method)的参数

让我们看一些例子:

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))

然后,这里发生的是我们为分配了一个新template.Templatet,这是解析的结果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".

现在应该很清楚模板名称的作用以及它的来源。



 类似资料:
  • 问题内容: 我当前的目录结构如下所示: 该文件用于在期间读入模板文件。 单元测试按预期工作。但是,我现在正在尝试对其进行单元测试,并且都将其导入,并且在尝试打开时会感到恐慌。 我尝试将模板名称指定为相对目录(“ ./foo.tmpl”),完整目录(“〜/ go / src / github.com / App / Template / foo.tmpl”),相对于应用程序目录(“ /App/Tem

  • 问题内容: 当我尝试使用和时,它注意到Go模板很奇怪。以下代码按预期工作: 但是,当我尝试将模板放在文件中时,它不起作用(说:): 使用template.html: 知道为什么吗?这是一个错误吗?有没有更简单的方法在模板中使用方法/功能? 问题答案: ParseFiles可能会使用更好的文档。一个模板对象可以包含多个模板,每个模板都有一个名称。如果查看ParseFiles的实现,则会看到它使用 文

  • "Pay attention to what you hear; the measure you give will be the measure you get, and still more will be given you. For to those who have, more will be given; and from those who have nothing, even wh

  • 前面我们学习了一些 Helm 模板中的一些常用使用方法,但是我们都是操作的一个模板文件,在实际的应用中,很多都是相对比较复杂的,往往会超过一个模板,如果有多个应用模板,我们应该如何进行处理呢?这就需要用到新的概念:命名模板。 命名模板我们也可以称为子模板,是限定在一个文件内部的模板,然后给一个名称。在使用命名模板的时候有一个需要特别注意的是:模板名称是全局的,如果我们声明了两个相同名称的模板,最后

  • 我希望输出日志消息的方式与使用bash“logger”命令的方式完全相同,但在Java中使用Log4j: 在尝试了许多不同的模式后,我无法再现相同的输出。知道怎么写这个图案吗? 谢谢你,

  • 我有一个rails应用程序,使用angularjs进行客户端开发。我尝试加载位于“app/assets/javascripts/templates/”中的模板: 但是我总是得到一个错误:错误:[$compile: tpload]未能加载模板:/index.html。 我试图将“templates”文件夹从javascripts-app/assets/templates中移出,并通过在config/