我正在尝试定义在模板条件中使用的自定义Go函数。我要实现的是:如果给定的参数是IPv4地址,则模板将输出 IPv4:[argument] 否则它将输出
IPv6:[argument] 。
为此,我创建了一个像这样的模板:
{{ range .Addresses }}
{{ if IsIPv4 . }}
IPv4: {{ . }}
{{ else }}
IPv6: {{ . }}
{{ end }}
{{ end }}
如您所见,我创建了一个名为 IsIPv4 的新函数,该函数接受字符串参数,并给定参数返回true或false。这是代码:
var (
errNotAnIPAddress = errors.New("The argument is not an IP address")
)
func isIPv4(address string) (bool, error) {
ip := net.ParseIP(address)
if ip == nil {
return false, errNotAnIPAddress
}
return (ip.To4() != nil), nil
}
在执行模板时,我没有任何错误,但是在尝试评估 {{如果IsIPv4 时,执行似乎停止了 。 }} 。
当然,在尝试解析和执行模板之前先对函数进行映射。
funcMap := template.FuncMap{
"IsIPv4": isIPv4,
}
我刚接触Go,可能已经错过了一些东西(也许很明显?)。
为了进行一点调试,我尝试删除模板中的IsIPv4调用,并给出类似 {{if 的条件 。 }} 。结果是始终输出
IPv4:[IP地址] 。这对我来说很有意义。
我还查看了诸如 eq 之类的预定义Go功能,看来我正在尝试重现相同的想法,但没有成功。
TL; DR;
您必须检查error
返回的值,template.Execute()
或者template.ExecuteTemplate()
它将告诉您为什么它不适合您。
首先,执行不会惊慌,因为它只会返回错误。您检查一下,您可能会立即知道出了什么问题:
if err := t.Execute(os.Stdout, data); err != nil {
panic(err)
}
接下来可能出问题的原因:您必须 在 解析模板 之前
注册自定义函数,因为模板引擎需要能够静态分析模板,并且它需要事先知道这IsIPv4
是一个函数名:
t := template.Must(template.New("").Funcs(template.FuncMap{
"IsIPv4": isIPv4,
}).Parse(templ))
另一个潜在的错误是isIPv4()
期望类型为的值string
,并且您可能会传递不同类型的值。
nil
如果您打算停止执行模板,则为模板注册的自定义功能应仅返回非错误。因为这是如果您返回的情况error
。template.FuncMap
:
[…]如果在执行期间第二个(错误)返回值的计算结果为非零,则执行终止,并且Execute返回该错误。
这是一个使用您的模板和isIPv4()
函数的工作示例:
t := template.Must(template.New("").Funcs(template.FuncMap{
"IsIPv4": isIPv4,
}).Parse(templ))
m := map[string]interface{}{
"Addresses": []string{"127.0.0.1", "0:0:0:0:0:0:0:1"},
}
if err := t.Execute(os.Stdout, m); err != nil {
panic(err)
}
输出(在Go Playground上尝试):
IPv4: 127.0.0.1
IPv6: 0:0:0:0:0:0:0:1
上面的程序打印以下错误:
传递无效的IP:
"Addresses": []string{"127.0.0.1.9"},
输出:
panic: template: :2:6: executing "" at <IsIPv4 .>: error calling IsIPv4:
The argument is not an IP address
传递非string
值:
"Addresses": []interface{}{2},
输出:
panic: template: :2:13: executing "" at <.>: wrong type for value; expected string; got int
模板解析 后 尝试注册您的自定义函数:
t := template.Must(template.New("").Parse(templ))
t.Funcs(template.FuncMap{
"IsIPv4": isIPv4,
})
输出:
panic: template: :2: function "IsIPv4" not defined
问题内容: 使用我正在尝试在模板中使用自己的功能之一。不幸的是,我无法使用go模板的功能映射功能。我得到的只是以下错误: 简化的测试用例如下所示(): 我有以下简单模板(): 这是1.1.1。 问题答案: IIRC,必须在解析模板之前定义模板功能图。下面的代码似乎有效。
问题内容: 我有一个使用Bootstrap中的标记的表单,如下所示: 这里有很多样板代码,我想简化为一个新的指令-form-input,如下所示: 产生: 我通过一个简单的模板完成了很多工作。 但是,当我开始添加更多高级功能时,我就陷入了困境。 如何在模板中支持默认值? 我想在指令中将“ type”参数公开为可选属性,例如: 但是,如果未指定任何内容,则默认为。我该如何支持? 如何根据属性的存在/
从MinDoc v0.13及以上版本开始支持自定义模板(仅Markdown编辑器)。 创建自定义模板 用户可在编辑项目时将编辑器内的内容报错为模板: 点击保存按钮右侧的公文包按钮会弹出保存为模板的界面: 填写模板名称点击立即保存即可。 全局模板是指,在其他项目中可用,目前仅支持管理员保存全局模板,非管理员及时选中了全局,保存时也是仅项目内可用。 使用自定义模板 点击编辑器上的模板按钮可以显示选择模
我刚刚用打字稿开始了一个新的反应项目,在功能组件中定义自定义道具时遇到了困难。 我查找了如何定义自定义道具,并找到了一种定义接口的方法,该接口详细描述了我传递给函数的道具类型,但是当我试图在我的主应用程序上运行它时,我得到一个错误消息 类型“{ digit: number; }”不能分配给类型“IntrinsicAttributes”。属性“数字”在类型“内部属性”上不存在。TS2322 我的代码
问题内容: 我将AngularJS用作前端JS库,并在Revel框架中使用Go模板来在后端生成标记。 但是Go和Angular 在模板中都使用和分隔符。如何在Go中转义它们以将它们传递给AngularJS? 问题答案: 我不知道如何转义它,但是您可以选择其他定界符,而不是使用: 根据邮件列表,这可能是最佳选择。争论是,如果您逃避了它,您的模板将很难阅读,因此无论如何更改定界符而不是尝试破解它可能会
问题内容: 我刚刚开始使用Twitter的Bootstrap,并且想知道自定义的“最佳实践”是什么。我想开发一种系统,该系统将利用css模板(Bootstrap或其他)的所有功能,完全(轻松)地进行修改,具有可持续性(即–从Twitter发布下一版本的Bootstrap时,我不会)不必重新开始。 例如,我想将背景图像添加到顶部导航中。看来有3种方法可以解决此问题: 修改bootstrap.css中