Tyl*_*ick 16 ruby go-templates
我该怎么做这样的事情:
{{ $use_ssl := (ne $.Env.CERT_NAME "") }}
Run Code Online (Sandbox Code Playgroud)
哪里$.Env.CERT_NAME可能是零/未定义.如果它是nil,则会出现此错误:
at <ne $.Env.CERT_NAME "">: error calling ne: invalid type for comparison
Run Code Online (Sandbox Code Playgroud)
注意:我无法控制传入Go模板的对象,因此必须在模板本身内完全解决这个问题.
我试图通过首先检查它是否为非空来解决:
{{ $use_ssl := ( ($.Env.CERT_NAME) && (ne $.Env.CERT_NAME "") ) }}
Run Code Online (Sandbox Code Playgroud)
但它给出了这个错误:
unexpected "&" in operand
Run Code Online (Sandbox Code Playgroud)
所以我切换到这个,这在语法上是允许的:
{{ $use_ssl := (and ($.Env.CERT_NAME) (ne $.Env.CERT_NAME "") ) }}
Run Code Online (Sandbox Code Playgroud)
但后来我失去了我对操作员的短路评估,我&&又回到了这个错误:
at <ne $.Env.CERT_NAME ...>: error calling ne: invalid type for comparison
Run Code Online (Sandbox Code Playgroud)
好吧,我想,如果我不能用一个漂亮的单行,并且Go没有三元运算符,那很好,我只会用惯用的Go方式来做,这显然是if/else.
{{ if $.Env.CERT_NAME }}
{{ $use_ssl := (ne $.Env.CERT_NAME "") }}
{{ else }}
{{ $use_ssl := false }}
{{ end }}
Run Code Online (Sandbox Code Playgroud)
但当然我遇到了范围问题,因为if莫名其妙地(或者至少令人讨厌)创建了一个新的变量范围(与我更习惯的Ruby/ERB模板不同),所以显然我甚至不能这样做:
{{ if $.Env.CERT_NAME }}
{{ $use_ssl := true }}
{{ else }}
{{ $use_ssl := false }}
{{ end }}
# $use_ssl: {{ $use_ssl }}
Run Code Online (Sandbox Code Playgroud)
现在没有收到此错误:
undefined variable "$use_ssl"
Run Code Online (Sandbox Code Playgroud)
"没有汗水",我想.我只是在外部范围内声明变量,因此它将具有正确的范围,内部范围仍然可以更改该变量(具有外部范围的变量).(顺便说一下,这就是它在Ruby中的工作方式.)
不,显然所有这一切都是创建2个不同的变量,具有相同的名称,但不同的范围(如何混淆!):
{{ $use_ssl := false }}
{{ if $.Env.CERT_NAME }}
{{ $use_ssl := true }}
# $use_ssl: {{ $use_ssl }}
{{ else }}
{{ $use_ssl := false }}
{{ end }}
# $use_ssl: {{ $use_ssl }}
# $use_ssl: true
# $use_ssl: false
Run Code Online (Sandbox Code Playgroud)
我也试过像这样内联if语句:
{{ $use_ssl := if $.Env.CERT_NAME { true } }}
Run Code Online (Sandbox Code Playgroud)
但是这给出了这个错误:
unexpected <if> in command
Run Code Online (Sandbox Code Playgroud)
显然if语句不能像Go中的表达式一样用在Ruby中吗?
如果我尝试在C的三元运算符的惯用Go等价物中建议的三元运算符的各种替代方法,我也会遇到语法错误?, 喜欢:
c := map[bool]int{true: 1, false: 0} [5 > 4]
Run Code Online (Sandbox Code Playgroud)
当然,您可以从内部作用域中的外部作用域读取变量,$.something但是如何在内部作用域中进行设置 $.something?
那么我错过了什么?这是否可以在Go模板中使用?
Go模板(我是他们的新手)似乎非常有限.几乎你在Go中可以做的一切都不可能在模板中完成.但希望有一个解决方法......
http://play.golang.org/p/SufZdsx-1v有一个聪明的解决方法,包括创建一个新对象,{{$hasFemale := cell false}}然后设置一个值$hasFemale.Set true,但是如何在不访问评估模板的代码的情况下做类似的事情(他们在哪里打电话template.FuncMap)?
https://groups.google.com/forum/#!topic/golang-nuts/MUzNZ9dbHrg
这是我与Go有关的最大(也是唯一)问题.我根本不明白为什么还没有实现这个功能.
当模板包在通用上下文中使用时(例如,使用任意json文件执行任意模板文件),您可能没有做预先计算的奢侈.
https://github.com/golang/go/issues/10608
这可能是设计的,但如果有办法在条件之外获得更改的$ v,那将是非常好的.
这是我们在Hugo(https://github.com/spf13/hugo)上解决的#1模板问题.我们现在添加了一个hack [
$.Scratch.Set "v1" 123]来解决它...
如果更新范围而不是声明变量,则通过使用set或使用,merge您将能够在if子句之外访问它.
{{- if eq .podKind "core" -}}
{{- $dummy := set . "matchNodePurpose" .Values.scheduling.corePods.nodeAffinity.matchNodePurpose }}
{{- else if eq .podKind "user" -}}
{{- $dummy := set . "matchNodePurpose" .Values.scheduling.userPods.nodeAffinity.matchNodePurpose }}
{{- end -}}
# Will now output what you decided within an if/else if clause
{{- .matchNodePurpose }}
Run Code Online (Sandbox Code Playgroud)
我在Helm模板的上下文中遇到了同样的问题,这些模板是预先安装了一些附加功能的模板,例如Sprig.
2018年3月28日,在这个pr中,一个Terenary操作员被添加到Sprig,及时Helm将让他们解决你和我的问题.
terenary
true | ternary "b" "c" 将返回 "b"
false | ternary "b" "c" 将返回 "c"
如果您使用赋值运算符而不是定义运算符,则第四次尝试会起作用:
{{ $use_ssl := false }}
{{ if $.Env.CERT_NAME }}
{{ $use_ssl = true }} # notice the missing colon!
{{ else }}
{{ $use_ssl = false }}
{{ end }}
Run Code Online (Sandbox Code Playgroud)
我想我可能已经找到解决我特定问题的方法,尽管我希望听到其他更普遍解决该问题的答案。
在https://github.com/jwilder/nginx-proxy/blob/1e0b930/nginx.tmpl#L91中跨过此行:
{{ $default_host := or ($.Env.DEFAULT_HOST) "" }}
Run Code Online (Sandbox Code Playgroud)
这给了我另一个尝试的想法。我猜解决方案是结合使用or并设置额外的临时变量...
{{ $cert_name := or $.Env.CERT_NAME "" }}
{{ $use_ssl := ne $cert_name "" }}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5810 次 |
| 最近记录: |