一尘不染

Golang模板引擎管道

go

我有一个Golang模板,定义如下

{{- define "test" -}}
{{- printf "%s" .Name | trunc 24 -}}
{{- end -}}

然后在我的一个文件中使用它:

{{ template "test" . }}

“测试”之后,点是什么意思?Golang模板文档说:

{{template "name" pipeline}}
The template with the specified name is executed with dot set
to the value of the pipeline.

但是我不确定是什么管道。阅读文档没有结果,有人可以再解释一次吗?

另外,为什么我们必须以点开始的值?例如{{ - printf "%s" .Name | trunc 24 -}}。这也是一种管道吗?

先感谢您!


阅读 354

收藏
2020-07-02

共1个答案

一尘不染

有2个template软件包,text/templatehtml/template

它们具有相同的接口,但是该html/template程序包用于生成安全的HTML输出,以防止代码注入,因此应使用该程序包,而不是text/template在输出为HTML时使用。

由于它们具有相同的界面,但是html/template提供了一些额外的功能(对插入的数据进行上下文转义),因此仅在上记录了基础知识和原理text/html,而html/template大多数文献则集中在详细说明额外内容上。

话虽如此,“管道”属于基础。它记录在管道text/template部分:

流水线

管道是“命令”的可能链接的序列。命令是一个简单的值(参数)或函数或方法调用,可能带有多个参数:

Argument
    The result is the value of evaluating the argument.
.Method [Argument...]
    The method can be alone or the last element of a chain but,
    unlike methods in the middle of a chain, it can take arguments.
    The result is the value of calling the method with the
    arguments:
        dot.Method(Argument1, etc.)
functionName [Argument...]
    The result is the value of calling the function associated
    with the name:
        function(Argument1, etc.)
    Functions and function names are described below.

通过用流水线字符“
|”分隔命令序列,可以“链接”流水线。在链式管道中,每个命令的结果作为以下命令的最后一个参数传递。流水线中最终命令的输出是流水线的值。

“参数”和“管道”是对数据的评估。

“点”
.基本上是一个光标,指向执行模板时传递的数据结构中的某处。点的起始值是您传递的值,但是许多操作(例如{{range}}或)都会修改该点{{with}}

执行模板将遍历结构并设置光标,并用句点“。”表示。并在执行过程中将其称为“点”到结构中当前位置的值。

因此,在编写时.Name,这表示点当前指向的值,您要引用其字段或方法或称为的键Name。例如,如果您传递struct,则模板的开头.Name将表示struct字段(Name如果存在)或其命名为的方法Name()

调用/包含另一个模板时,您可以告诉您将什么值传递给其执行。编写时{{template "something" .}},这意味着您要将当前由点指向的值传递给模板执行。如果只希望传递Name点所指向的结构的字段,则可以像那样进行{{template "something" .Name}}

您在管道中传递的值{{template}}将成为调用的其他模板内的点。

因此,在处理/渲染模板时,点可能会更改,并且“仅”指向最初传递给模板执行的部分值。通常它很方便,或者仍然需要达到原始值,而不仅仅是光标。为此,模板包提供了$

开始执行时,将$设置为传递给Execute的数据参数,即dot的起始值。

因此,即使您位于{{range}}例如(将点设置为要遍历的数组/ slice
/映射的连续元素)内,您仍然可以伸手并引用传递给该对象的值的任何其他部分模板执行。

因此,例如,如果您遍历像这样的书{{range .Books}},并且需要Name原始传递的struct
的字段,则可以在内部执行{{range}}以下操作:

{{range .Books}}
    Title: {{.Title}}
    Original name: {{$.Name}}
{{end}}
2020-07-02