在Go的html/template中有可选的模板吗?

huangapple go评论83阅读模式
英文:

Optional templates in go html/template?

问题

给定一组模板,如下所示:

layout.tpl

<html>
<head>
<title>Some title</title>
{{template extracss}}
</head>
<body>
<h1>Page title</h1>
{{template content .}}
</body>
</html>

home.tpl

{{define "content"}}
<p>page content goes here</p>
{{end}}

edit.tpl

{{define "content"}}
<form>form content goes here</form>
{{end}}

{{define "extracss"}}<style>body{background:pink}</style>{{end}}

使用以下代码来渲染模板:

func Render(w http.ResponseWriter, tmpname string, data interface{}) {

    t, err := template.ParseFiles("views/layout.tpl", "views/"+tmpname+".tpl")
    // parse error
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
       
    if err := t.Execute(w, data); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

edit.tpl将正确渲染,因为它定义了'extracss',而home.tpl不会,因为模板解析器正确地指出'no such template "extracss"'。

那么我应该使用什么机制来允许使用'可选'模板?

有什么想法吗?

英文:

Given a set of templates like:

layout.tpl

<html>
<head>
<title>Some title</title>
{{template extracss}}
</head>
<body>
<h1>Page title</h1>
{{template content .}}
</body>
</html>

home.tpl

{{define "content"}}
<p>page content goes here</p>
{{end}}

edit.tpl

{{define "content"}}
<form>form content goes here</form>
{{end}}

{{define "extracss"}}<style>body{background:pink}</style>{{end}}

using this to render the template:

func Render(w http.ResponseWriter, tmpname string, data interface{}) {

    t, err := template.ParseFiles("views/layout.tpl", "views/"+tmpname+".tpl")
    // parse error
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
       
    if err := t.Execute(w, data); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

edit.tpl will render correctly as it has 'extracss' defined, home.tpl will not as the template parser rightly says 'no such template "extracss"'.

So what mechanism would I use to allow 'optional' templates to be used?

Any ideas?

答案1

得分: 4

一个空的定义是有效的:{{define "extracss"}}{{end}}。这可能不是非常优雅,但很容易理解。

请注意,您不需要重复空的定义。您可以将它们放入主模板中,并仅在需要时在包含的模板中重新定义它们。

英文:

An empty define works: {{define "extracss"}}{{end}}. It's maybe not super elegant, but simple to understand.

Note that you don't need to repeat the empty defines. You can put them into your master template and redefine them in the included templates only if needed.

答案2

得分: 1

@thomas的答案很棒,但我发现他写的内容有歧义,试图将其翻译成代码浪费了很多时间。

这是一个可行的代码(我相信这就是他建议的):

layout.tpl

<html>
  <head>
    <title>Some title</title>
    {{template extracss}}
    {{define "extracss"}}{{end}}
  </head>
  <body>
    <h1>Page title</h1>
    {{template content .}}
  </body>
</html>

home.tpl

{{define "content"}}
  <p>页面内容放在这里</p>
{{end}}

edit.tpl

{{define "content"}}
  <form>表单内容放在这里</form>
{{end}}

{{define "extracss"}}<style>body{background:pink}</style>{{end}}

使用以下代码来渲染模板:

func Render(w http.ResponseWriter, tmpname string, data interface{}) {

    t, err := template.ParseFiles("views/layout.tpl", "views/"+tmpname+".tpl")
    // 解析错误
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
       
    if err := t.Execute(w, data); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}
英文:

The answer from @thomas is awesome, but I found what he wrote ambiguous and wasted a lot of time trying to translate it into code.

Here's code that works (and I believe is what he's suggesting):

layout.tpl

&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Some title&lt;/title&gt;
    {{template extracss}}
    {{define &quot;extracss&quot;}}{{end}}
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;Page title&lt;/h1&gt;
    {{template content .}}
  &lt;/body&gt;
&lt;/html&gt;

home.tpl

{{define &quot;content&quot;}}
&lt;p&gt;page content goes here&lt;/p&gt;
{{end}}

edit.tpl

{{define &quot;content&quot;}}
&lt;form&gt;form content goes here&lt;/form&gt;
{{end}}

{{define &quot;extracss&quot;}}&lt;style&gt;body{background:pink}&lt;/style&gt;{{end}}

using this to render the template:

func Render(w http.ResponseWriter, tmpname string, data interface{}) {

    t, err := template.ParseFiles(&quot;views/layout.tpl&quot;, &quot;views/&quot;+tmpname+&quot;.tpl&quot;)
    // parse error
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
       
    if err := t.Execute(w, data); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

答案3

得分: 0

也许在问题提出时这个功能还不可用,但是似乎可以使用block来实现这个目的:

>{{block &quot;name&quot; pipeline}} T1 {{end}}
>
>block是定义模板的简写形式
{{define &quot;name&quot;}} T1 {{end}}
然后在适当的位置执行它
{{template &quot;name&quot; pipeline}}
典型的用法是定义一组根模板,然后通过重新定义块模板来进行自定义。

layout.tpl

&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Some title&lt;/title&gt;
    {{block &quot;extracss&quot; .}}{{end}}
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;Page title&lt;/h1&gt;
    {{block &quot;content&quot; .}}{{end}}
  &lt;/body&gt;
&lt;/html&gt;

home.tpl

{{define &quot;content&quot;}}
  &lt;p&gt;页面内容放在这里&lt;/p&gt;
{{end}}

edit.tpl

{{define &quot;content&quot;}}
  &lt;form&gt;表单内容放在这里&lt;/form&gt;
{{end}}

{{define &quot;extracss&quot;}}&lt;style&gt;body{background:pink}&lt;/style&gt;{{end}}
英文:

Perhaps this wasn't available at the time the question was asked but it seems that you can use block for this purpose:

>{{block &quot;name&quot; pipeline}} T1 {{end}}
>
>A block is shorthand for defining a template
{{define &quot;name&quot;}} T1 {{end}}
and then executing it in place
{{template &quot;name&quot; pipeline}}
The typical use is to define a set of root templates that are then customized by redefining the block templates within.

layout.tpl

&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Some title&lt;/title&gt;
    {{block &quot;extracss&quot; .}}{{end}}
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;Page title&lt;/h1&gt;
    {{block &quot;content&quot; .}}{{end}}
  &lt;/body&gt;
&lt;/html&gt;

home.tpl

{{define &quot;content&quot;}}
&lt;p&gt;page content goes here&lt;/p&gt;
{{end}}

edit.tpl

{{define &quot;content&quot;}}
&lt;form&gt;form content goes here&lt;/form&gt;
{{end}}

{{define &quot;extracss&quot;}}&lt;style&gt;body{background:pink}&lt;/style&gt;{{end}}

huangapple
  • 本文由 发表于 2013年3月25日 21:57:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/15616785.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定