如何在Go中使用常量字符串变量中的嵌套模板?

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

How do I use nested Templates from a constant string variable in Go?

问题

我一直在尝试在Go中使用嵌套模板,但是示例或帮助文档对我没有帮助,而其他3个博客中的示例也不是我想要的(其中一个接近,可能是唯一的方法,但我想确保)

好的,所以我的代码是用于App Engine的,在这里我将对服务器进行urlfetch,然后我想显示一些结果,比如Response、头部和正文。

const statusTemplate = `
{{define "RT"}}
Status      - {{.Status}}
Proto       - {{.Proto}}
{{end}}
{{define "HT"}}
{{range $key, $val := .}}
{{$key}} - {{$val}}
{{end}}
{{end}}
{{define "BT"}}
{{.}}
{{end}}
{{define "MT"}}
<html>
    <body>
        <pre>
-- Response --
{{template "RT"}}

--  Header  --
{{template "HT"}}

--   Body   --
{{template "BT"}}
        </pre>
    </body>
</html>
{{end}}
{{template "MT"}}`

func showStatus(w http.ResponseWriterm r *http.Request) {
    /*
     *  code to get:
     *  resp as http.Response
     *  header as a map with the header values
     *  body as an string wit the contents
     */
    t := template.Must(template.New("status").Parse(statusTemplate)
    t.ExecuteTemplate(w, "RT", resp)
    t.ExecuteTemplate(w, "HT", header)
    t.ExecuteTemplate(w, "BT", body)
    t.Execute(w, nil)
}

我的代码实际上输出了具有正确值的RT、HT和BT模板,然后输出了空的MT模板(MT代表主模板)。

那么...我如何使用字符串变量中的嵌套表单,使上述示例工作?

英文:

I have been trying to use nested templates in Go, however the Examples or help documents are not helping me, and examples in 3 other blogs are not what I'm looking for (one is close and maybe the only way but I want to make sure)

OK, so my code is for App Engine, in here I will be doing an urlfetch to a server, and then I want to show some results, like the Response, headers, and body.

const statusTemplate = `
{{define &quot;RT&quot;}}
Status      - {{.Status}}
Proto       - {{.Proto}}
{{end}}
{{define &quot;HT&quot;}}
{{range $key, $val := .}}
{{$key}} - {{$val}}
{{end}}
{{end}}
{{define &quot;BT&quot;}}
{{.}}
{{end}}
{{define &quot;MT&quot;}}
&lt;html&gt;
    &lt;body&gt;
        &lt;pre&gt;
-- Response --
{{template &quot;RT&quot;}}

--  Header  --
{{template &quot;HT&quot;}}

--   Body   --
{{template &quot;BT&quot;}}
        &lt;/pre&gt;
    &lt;/body&gt;
&lt;/html&gt;
{{end}}
{{template &quot;MT&quot;}}`

func showStatus(w http.ResponseWriterm r *http.Request) {
    /*
     *  code to get:
     *  resp as http.Response
     *  header as a map with the header values
     *  body as an string wit the contents
     */
    t := template.Must(template.New(&quot;status&quot;).Parse(statusTemplate)
    t.ExecuteTemplate(w, &quot;RT&quot;, resp)
    t.ExecuteTemplate(w, &quot;HT&quot;, header)
    t.ExecuteTemplate(w, &quot;BT&quot;, body)
    t.Execute(w, nil)
}

My code actually outputs the RT, HT, and BT templates with the correct values, and then it outputs the MT template empty (MT stands for main template).

So... How can I use nested forms from a string variable so that an example as the above works?

答案1

得分: 1

我认为你尝试使用嵌套模板的方法是错误的。如果你想在嵌套模板中定义.,你必须为调用嵌套模板时提供一个参数,就像你在ExecuteTemplate函数中做的那样:

{{define "RT"}}
状态      - {{.Status}}
协议       - {{.Proto}}
{{end}}
{{define "HT"}}
{{range $key, $val := .}}
{{$key}} - {{$val}}
{{end}}
{{end}}
{{define "BT"}}
{{.}}
{{end}}
{{define "MT"}}
<html>
    <body>
        <pre>
-- 响应 --
{{template "RT" .Resp}}

--  头部  --
{{template "HT" .Header}}

--   主体   --
{{template "BT" .Body}}
        </pre>
    </body>
</html>
{{end}}
{{template "MT"}}

你似乎忽略了一个重要的部分,那就是模板不会封装状态。当你执行一个模板时,引擎会根据给定的参数评估模板,然后将生成的文本写出。它不会保存参数或为将来的调用生成的任何内容。

##文档

相关部分的文档

> ###操作
>
> 这是操作的列表。"参数"和"管道"是数据的评估,下面详细定义。
>
> ...
>
> {{template "name"}}
> 使用空数据执行指定名称的模板。
>
> {{template "name" pipeline}}
> 使用管道的值将.设置为指定名称的模板执行。
>
> ...

希望这能解决你的问题。

英文:

I think the approach you try with nested templates is wrong. If you want . to be defined inside a nested template, you have to supply an argument to the call to the nested template, just as you do with the ExecuteTemplate function:

{{define &quot;RT&quot;}}
Status      - {{.Status}}
Proto       - {{.Proto}}
{{end}}
{{define &quot;HT&quot;}}
{{range $key, $val := .}}
{{$key}} - {{$val}}
{{end}}
{{end}}
{{define &quot;BT&quot;}}
{{.}}
{{end}}
{{define &quot;MT&quot;}}
&lt;html&gt;
    &lt;body&gt;
        &lt;pre&gt;
-- Response --
{{template &quot;RT&quot; .Resp}}

--  Header  --
{{template &quot;HT&quot; .Header}}

--   Body   --
{{template &quot;BT&quot; .Body}}
        &lt;/pre&gt;
    &lt;/body&gt;
&lt;/html&gt;
{{end}}
{{template &quot;MT&quot;}}

The important part you seem to miss is that templates do not encapsulate state. When you execute a template, the engine evaluates the template for the given argument and then writes out the generated text. It does not save the argument or anything that was generated for future invocations.

##Documentation

Relevant part of the documentation:

> ###Actions
>
> Here is the list of actions. "Arguments" and "pipelines" are
> evaluations of data, defined in detail below.
>
> ...
>
> {{template "name"}}
> The template with the specified name is executed with nil data.
>
> {{template "name" pipeline}}
> The template with the specified name is executed with dot set
> to the value of the pipeline.
>
> ...

I hope this clears up things.

答案2

得分: 0

请看这个教程:
http://javatogo.blogspot.com

里面解释了如何使用嵌套模板。

英文:

have a look at this tutorial:
http://javatogo.blogspot.com

there it is explained how to use nested templates.

huangapple
  • 本文由 发表于 2013年7月14日 15:07:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/17637332.html
匿名

发表评论

匿名网友

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

确定