樣板函數列表
Helm 包含許多您可以在樣板中使用的樣板函數。它們在此列出並按以下類別細分
邏輯和流程控制函數
Helm 包含許多邏輯和控制流程函數,包括 and、coalesce、default、empty、eq、fail、ge、gt、le、lt、ne、not、or 和 required。
and
傳回兩個或多個參數的布林 AND(第一個空參數或最後一個參數)。
and .Arg1 .Arg2
or
傳回兩個或多個參數的布林 OR(第一個非空參數或最後一個參數)。
or .Arg1 .Arg2
not
傳回其參數的布林否定。
not .Arg
eq
傳回參數的布林等式(例如,Arg1 == Arg2)。
eq .Arg1 .Arg2
ne
傳回參數的布林不等式(例如,Arg1 != Arg2)
ne .Arg1 .Arg2
lt
如果第一個參數小於第二個參數,則傳回布林值 true。否則傳回 false(例如,Arg1 < Arg2)。
lt .Arg1 .Arg2
le
如果第一個參數小於或等於第二個參數,則傳回布林值 true。否則傳回 false(例如,Arg1 <= Arg2)。
le .Arg1 .Arg2
gt
如果第一個參數大於第二個參數,則傳回布林值 true。否則傳回 false(例如,Arg1 > Arg2)。
gt .Arg1 .Arg2
ge
如果第一個參數大於或等於第二個參數,則傳回布林值 true。否則傳回 false(例如,Arg1 >= Arg2)。
ge .Arg1 .Arg2
default
要設定簡單的預設值,請使用 default
default "foo" .Bar
在上面,如果 .Bar
評估為非空值,則將使用它。但如果它是空的,則會改為傳回 foo
。
「空」的定義取決於類型
- 數值:0
- 字串:""
- 列表:
[]
- 字典:
{}
- 布林值:
false
- 並且始終為
nil
(也稱為 null)
對於結構,沒有空的定義,因此結構永遠不會傳回預設值。
required
使用 required
指定必須設定的值
required "A valid foo is required!" .Bar
如果 .Bar
為空或未定義(請參閱 default 了解如何評估),則樣板將不會渲染並將改為傳回提供的錯誤訊息。
empty
如果給定值被視為空,則 empty
函數傳回 true
,否則傳回 false
。空值列在 default
部分中。
empty .Foo
請注意,在 Go 樣板條件中,會為您計算空值。因此,您很少需要 if not empty .Foo
。相反,只需使用 if .Foo
。
fail
無條件地傳回一個空的 string
和一個帶有指定文字的 error
。這在其他條件已確定樣板渲染應失敗的情況下很有用。
fail "Please accept the end user license agreement"
coalesce
coalesce
函數接受一個值列表並傳回第一個非空值。
coalesce 0 1 2
上面傳回 1
。
此函數適用於掃描多個變數或值
coalesce .name .parent.name "Matt"
上面將首先檢查 .name
是否為空。如果不是,它將傳回該值。如果它是空的,coalesce
將評估 .parent.name
是否為空。最後,如果 .name
和 .parent.name
都為空,它將傳回 Matt
。
ternary
ternary
函數接受兩個值和一個測試值。如果測試值為真,則將傳回第一個值。如果測試值為空,則將傳回第二個值。這類似於 C 語言和其他程式語言中的三元運算符。
真測試值
ternary "foo" "bar" true
or
true | ternary "foo" "bar"
上面傳回 "foo"
。
假測試值
ternary "foo" "bar" false
or
false | ternary "foo" "bar"
上面傳回 "bar"
。
字串函數
Helm 包含以下字串函數:abbrev、abbrevboth、camelcase、cat、contains、hasPrefix、hasSuffix、indent、initials、kebabcase、lower、nindent、nospace、plural、print、printf、println、quote、randAlpha、randAlphaNum、randAscii、randNumeric、repeat、replace、shuffle、snakecase、squote、substr、swapcase、title、trim、trimAll、trimPrefix、trimSuffix、trunc、untitle、upper、wrap 和 wrapWith。
從其各部分的組合傳回一個字串。
print "Matt has " .Dogs " dogs"
非字串的類型會在可能的情況下轉換為字串。
請注意,當兩個相鄰的參數不是字串時,它們之間會添加一個空格。
println
工作方式與 print 相同,但在結尾添加一個新行。
printf
根據格式化字串和按順序傳遞給它的參數傳回一個字串。
printf "%s has %d dogs." .Name .NumberDogs
要使用的佔位符取決於傳入參數的類型。這包括
通用
%v
預設格式的值- 列印字典時,加號標誌 (%+v) 會添加欄位名稱
%%
字面百分號;不消耗任何值
布林值
%t
單詞 true 或 false
整數
%b
基數 2%c
由相應的 Unicode 代碼點表示的字元%d
基數 10%o
基數 8%O
基數 8,帶有 0o 前綴%q
安全轉義的單引號字元文字%x
基數 16,a-f 使用小寫字母%X
基數 16,A-F 使用大寫字母%U
Unicode 格式:U+1234;與 "U+%04X" 相同
浮點數和複數成分
%b
指數為 2 的冪的十進制非科學計數法,例如 -123456p-78%e
科學計數法,例如 -1.234456e+78%E
科學計數法,例如 -1.234456E+78%f
小數點但沒有指數,例如 123.456%F
%f 的同義詞%g
對於大指數為 %e,否則為 %f。%G
對於大指數為 %E,否則為 %F%x
十六進制表示法(帶有 2 的十進制冪指數),例如 -0x1.23abcp+20%X
大寫十六進制表示法,例如 -0X1.23ABCP+20
字串和位元組切片(使用這些動詞等效處理)
%s
字串或切片的未解釋位元組%q
安全轉義的雙引號字串%x
16 進位,小寫,每個位元組兩個字元%X
16 進位,大寫,每個位元組兩個字元
Slice(切片)
%p
第 0 個元素的地址,以 16 進位表示法,前面加上 0x
trim(修剪)
trim
函數會移除字串兩側的空白字元
trim " hello "
以上程式碼會產生 hello
trimAll(修剪全部)
移除字串前後指定的字元
trimAll "$" "$5.00"
以上程式碼會傳回 5.00
(作為字串)。
trimPrefix(修剪前綴)
僅修剪字串的前綴
trimPrefix "-" "-hello"
以上程式碼會傳回 hello
trimSuffix(修剪後綴)
僅修剪字串的後綴
trimSuffix "-" "hello-"
以上程式碼會傳回 hello
lower(轉小寫)
將整個字串轉換為小寫
lower "HELLO"
以上程式碼會傳回 hello
upper(轉大寫)
將整個字串轉換為大寫
upper "hello"
以上程式碼會傳回 HELLO
title(標題化)
轉換為標題大小寫
title "hello world"
以上程式碼會傳回 Hello World
untitle(取消標題化)
移除標題大小寫。untitle "Hello World"
會產生 hello world
。
repeat(重複)
將字串重複多次
repeat 3 "hello"
以上程式碼會傳回 hellohellohello
substr(子字串)
從字串中取得子字串。它需要三個參數
- start(起始位置,整數)
- end(結束位置,整數)
- string(字串)
substr 0 5 "hello world"
以上程式碼會傳回 hello
nospace(無空格)
移除字串中的所有空白字元。
nospace "hello w o r l d"
以上程式碼會傳回 helloworld
trunc(截斷)
截斷字串
trunc 5 "hello world"
以上程式碼會產生 hello
。
trunc -5 "hello world"
以上程式碼會產生 world
。
abbrev(縮寫)
使用省略號 (...
) 截斷字串
參數
- 最大長度
- 字串
abbrev 5 "hello world"
以上程式碼會傳回 he...
,因為它會將省略號的寬度計入最大長度。
abbrevboth(兩側縮寫)
縮寫兩側
abbrevboth 5 10 "1234 5678 9123"
以上程式碼會產生 ...5678...
它需要
- 左側偏移量
- 最大長度
- 字串
initials(首字母縮寫)
給定多個單字,取每個單字的第一個字母並組合。
initials "First Try"
以上程式碼會傳回 FT
randAlphaNum、randAlpha、randNumeric 和 randAscii
這四個函數會產生密碼學上安全的(使用 crypto/rand
)隨機字串,但具有不同的基本字元集
randAlphaNum
使用0-9a-zA-Z
randAlpha
使用a-zA-Z
randNumeric
使用0-9
randAscii
使用所有可列印的 ASCII 字元
它們 masing-masing 只需要一個參數:字串的整數長度。
randNumeric 3
以上程式碼會產生一個包含三位數字的隨機字串。
wrap(換行)
在指定的欄數處換行文字
wrap 80 $someText
以上程式碼會在 80 個欄數處換行 $someText
中的字串。
wrapWith(使用指定字元換行)
wrapWith
的功能與 wrap
相同,但允許您指定用於換行的字串。(wrap
使用 \n
)
wrapWith 5 "\t" "Hello World"
以上程式碼會產生 Hello World
(其中空白字元是 ASCII Tab 字元)
contains(包含)
測試一個字串是否包含在另一個字串中
contains "cat" "catch"
以上程式碼會傳回 true
,因為 catch
包含 cat
。
hasPrefix 和 hasSuffix(具有前綴和後綴)
hasPrefix
和 hasSuffix
函數會測試字串是否具有指定的前綴或後綴
hasPrefix "cat" "catch"
以上程式碼會傳回 true
,因為 catch
具有前綴 cat
。
quote 和 squote(雙引號和單引號)
這些函數會將字串用雙引號 (quote
) 或單引號 (squote
) 包起來。
cat(串接)
cat
函數會將多個字串串接成一個,並以空格分隔
cat "hello" "beautiful" "world"
以上程式碼會產生 hello beautiful world
indent(縮排)
indent
函數會將指定字串中的每一行縮排到指定的縮排寬度。這在對齊多行字串時很有用
indent 4 $lots_of_text
以上程式碼會將每一行文字縮排 4 個空格字元。
nindent(新增一行並縮排)
nindent
函數與 indent 函數相同,但會在字串開頭加上一個新行。
nindent 4 $lots_of_text
以上程式碼會將每一行文字縮排 4 個空格字元,並在開頭加上一個新行。
replace(取代)
執行簡單的字串取代。
它需要三個參數
- 要取代的字串
- 取代成的字串
- 來源字串
"I Am Henry VIII" | replace " " "-"
以上程式碼會產生 I-Am-Henry-VIII
plural(複數化)
將字串複數化。
len $fish | plural "one anchovy" "many anchovies"
在以上程式碼中,如果字串的長度為 1,則會印出第一個參數 (one anchovy
)。否則,會印出第二個參數 (many anchovies
)。
參數為
- 單數字串
- 複數字串
- 長度整數
注意:Helm 目前不支援具有更複雜複數化規則的語言。而且 0
被視為複數,因為英語將其視為複數 (zero anchovies
)。
snakecase(蛇形命名法)
將字串從 camelCase 轉換為 snake_case。
snakecase "FirstName"
以上程式碼會產生 first_name
。
camelcase(駝峰命名法)
將字串從 snake_case 轉換為 CamelCase
camelcase "http_server"
以上程式碼會產生 HttpServer
。
kebabcase(烤肉串命名法)
將字串從 camelCase 轉換為 kebab-case。
kebabcase "FirstName"
以上程式碼會產生 first-name
。
swapcase(大小寫交換)
使用基於單字的演算法交換字串的大小寫。
轉換演算法
- 大寫字元轉換為小寫
- 標題大小寫字元轉換為小寫
- 空白字元後或開頭的小寫字元轉換為標題大小寫
- 其他小寫字元轉換為大寫
- 空白字元由 unicode.IsSpace(char) 定義
swapcase "This Is A.Test"
以上程式碼會產生 tHIS iS a.tEST
。
shuffle(洗牌)
洗牌字串。
shuffle "hello"
以上程式碼會將 hello
中的字母隨機排列,可能會產生 oelhl
。
類型轉換函數
Helm 提供以下類型轉換函數
atoi
:將字串轉換為整數。float64
:轉換為float64
。int
:轉換為系統寬度的int
。int64
:轉換為int64
。toDecimal
:將 Unix 八進位制轉換為int64
。toString
:轉換為字串。toStrings
:將列表、切片或陣列轉換為字串列表。toJson
(mustToJson
):將列表、切片、陣列、字典或物件轉換為 JSON。toPrettyJson
(mustToPrettyJson
):將列表、切片、陣列、字典或物件轉換為縮排的 JSON。toRawJson
(mustToRawJson
):將列表、切片、陣列、字典或物件轉換為 HTML 字元未逸出的 JSON。fromYaml
:將 YAML 字串轉換為物件。fromJson
:將 JSON 字串轉換為物件。fromJsonArray
:將 JSON 陣列轉換為列表。toYaml
:將列表、切片、陣列、字典或物件轉換為縮排的 yaml,可用於從任何來源複製 yaml 塊。此函數等效於 GoLang yaml.Marshal 函數,請參閱此處的文檔:https://pkg.go.dev/gopkg.in/yaml.v2#MarshaltoToml
:將列表、切片、陣列、字典或物件轉換為 toml,可用於從任何來源複製 toml 塊。fromYamlArray
:將 YAML 陣列轉換為列表。
只有 atoi
要求輸入是特定類型。其他函數會嘗試將任何類型轉換為目標類型。例如,int64
可以將浮點數轉換為整數,也可以將字串轉換為整數。
toStrings
給定一個類似列表的集合,產生一個字串切片。
list 1 2 3 | toStrings
以上程式碼會將 1
轉換為 "1"
,將 2
轉換為 "2"
,依此類推,然後將它們作為列表傳回。
toDecimal
給定 Unix 八進位制權限,產生一個十進位制數。
"0777" | toDecimal
以上程式碼會將 0777
轉換為 511
,並將該值作為 int64 傳回。
toJson、mustToJson
toJson
函數會將項目編碼為 JSON 字串。如果項目無法轉換為 JSON,則該函數會傳回空字串。如果項目無法編碼為 JSON,則 mustToJson
會傳回錯誤。
toJson .Item
以上程式碼會傳回 .Item
的 JSON 字串表示形式。
toPrettyJson、mustToPrettyJson
toPrettyJson
函數會將項目編碼為漂亮的(縮排的)JSON 字串。
toPrettyJson .Item
以上程式碼會傳回 .Item
的縮排 JSON 字串表示形式。
toRawJson、mustToRawJson
toRawJson
函數會將項目編碼為 HTML 字元未逸出的 JSON 字串。
toRawJson .Item
以上程式碼會傳回 .Item
的未逸出 JSON 字串表示形式。
fromYaml
fromYaml
函數會接收 YAML 字串,並傳回一個可在模板中使用的物件。
檔案位於:yamls/person.yaml
name: Bob
age: 25
hobbies:
- hiking
- fishing
- cooking
{{- $person := .Files.Get "yamls/person.yaml" | fromYaml }}
greeting: |
Hi, my name is {{ $person.name }} and I am {{ $person.age }} years old.
My hobbies are {{ range $person.hobbies }}{{ . }} {{ end }}.
fromJson
fromJson
函數會接收 JSON 字串,並傳回一個可在模板中使用的物件。
檔案位於:jsons/person.json
{
"name": "Bob",
"age": 25,
"hobbies": [
"hiking",
"fishing",
"cooking"
]
}
{{- $person := .Files.Get "jsons/person.json" | fromJson }}
greeting: |
Hi, my name is {{ $person.name }} and I am {{ $person.age }} years old.
My hobbies are {{ range $person.hobbies }}{{ . }} {{ end }}.
fromJsonArray
fromJsonArray
函數會接收 JSON 陣列,並傳回一個可在模板中使用的列表。
檔案位於:jsons/people.json
[
{ "name": "Bob","age": 25 },
{ "name": "Ram","age": 16 }
]
{{- $people := .Files.Get "jsons/people.json" | fromJsonArray }}
{{- range $person := $people }}
greeting: |
Hi, my name is {{ $person.name }} and I am {{ $person.age }} years old.
{{ end }}
fromYamlArray
fromYamlArray
函數會接收 YAML 陣列,並傳回一個可在模板中使用的列表。
檔案位於:yamls/people.yml
- name: Bob
age: 25
- name: Ram
age: 16
{{- $people := .Files.Get "yamls/people.yml" | fromYamlArray }}
{{- range $person := $people }}
greeting: |
Hi, my name is {{ $person.name }} and I am {{ $person.age }} years old.
{{ end }}
正則表達式
Helm 包含以下正則表達式函數:regexFind (mustRegexFind)、regexFindAll (mustRegexFindAll)、regexMatch (mustRegexMatch)、regexReplaceAll (mustRegexReplaceAll)、regexReplaceAllLiteral (mustRegexReplaceAllLiteral)、regexSplit (mustRegexSplit)。
regexMatch、mustRegexMatch
如果輸入字串包含任何與正則表達式匹配的內容,則傳回 true。
regexMatch "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$" "test@acme.com"
以上程式碼會產生 true
如果出現問題,regexMatch
會發生恐慌,如果出現問題,mustRegexMatch
會向模板引擎傳回錯誤。
regexFindAll、mustRegexFindAll
傳回輸入字串中所有與正則表達式匹配的切片。最後一個參數 n 決定要傳回的子字串數量,其中 -1 表示傳回所有匹配項
regexFindAll "[2,4,6,8]" "123456789" -1
以上程式碼會產生 [2 4 6 8]
如果出現問題,regexFindAll
會發生恐慌,如果出現問題,mustRegexFindAll
會向模板引擎傳回錯誤。
regexFind、mustRegexFind
傳回輸入字串中正則表達式的第一個(最左側)匹配項
regexFind "[a-zA-Z][1-9]" "abcd1234"
以上程式碼會產生 d1
如果出現問題,regexFind
會發生恐慌,如果出現問題,mustRegexFind
會向模板引擎傳回錯誤。
regexReplaceAll、mustRegexReplaceAll
傳回輸入字串的副本,將 Regexp 的匹配項替換為替換字串 replacement。在字串替換內,$ 符號的解釋與 Expand 中相同,因此例如 $1 表示第一個子匹配項的文字
regexReplaceAll "a(x*)b" "-ab-axxb-" "${1}W"
以上程式碼會產生 -W-xxW-
如果出現問題,regexReplaceAll
會發生恐慌,如果出現問題,mustRegexReplaceAll
會向模板引擎傳回錯誤。
regexReplaceAllLiteral、mustRegexReplaceAllLiteral
傳回輸入字串的副本,將 Regexp 的匹配項替換為替換字串 replacement。替換字串會直接替換,而不使用 Expand
regexReplaceAllLiteral "a(x*)b" "-ab-axxb-" "${1}"
以上程式碼會產生 -${1}-${1}-
如果出現問題,regexReplaceAllLiteral
會發生恐慌,如果出現問題,mustRegexReplaceAllLiteral
會向模板引擎傳回錯誤。
regexSplit、mustRegexSplit
將輸入字串切片成由表達式分隔的子字串,並傳回這些表達式匹配項之間的子字串切片。最後一個參數 n
決定要傳回的子字串數量,其中 -1
表示傳回所有匹配項
regexSplit "z+" "pizza" -1
以上程式碼會產生 [pi a]
如果出現問題,regexSplit
會發生恐慌,如果出現問題,mustRegexSplit
會向模板引擎傳回錯誤。
密碼學和安全函數
Helm 提供了一些進階的密碼學函數。它們包括 adler32sum、buildCustomCert、decryptAES、derivePassword、encryptAES、genCA、genPrivateKey、genSelfSignedCert、genSignedCert、htpasswd、sha1sum 和 sha256sum。
sha1sum
sha1sum
函數接收一個字串,並計算其 SHA1 摘要。
sha1sum "Hello world!"
sha256sum
sha256sum
函數接收一個字串,並計算其 SHA256 摘要。
sha256sum "Hello world!"
以上將以「ASCII 編碼」格式計算 SHA 256 總和,此格式可以安全地列印。
adler32sum
adler32sum
函數接收一個字串,並計算其 Adler-32 校驗和。
adler32sum "Hello world!"
htpasswd
htpasswd
函數接收 username
和 password
,並產生密碼的 bcrypt
雜湊。結果可用於 Apache HTTP 伺服器 上的基本身份驗證。
htpasswd "myUser" "myPassword"
請注意,直接在範本中儲存密碼是不安全的。
derivePassword
derivePassword
函數可用於根據一些共享的「主密碼」約束來衍生特定密碼。此演算法有 詳細規範。
derivePassword 1 "long" "password" "user" "example.com"
請注意,將零件直接儲存在範本中被認為是不安全的。
genPrivateKey
genPrivateKey
函數會產生一個編碼成 PEM 區塊的新私鑰。
它會將以下其中一個值作為其第一個參數
ecdsa
:產生橢圓曲線 DSA 金鑰 (P256)dsa
:產生 DSA 金鑰 (L2048N256)rsa
:產生 RSA 4096 金鑰
buildCustomCert
buildCustomCert
函數允許自訂憑證。
它接受以下字串參數
- 以 Base64 編碼的 PEM 格式憑證
- 以 Base64 編碼的 PEM 格式私鑰
它會傳回具有以下屬性的憑證物件
Cert
:PEM 編碼的憑證Key
:PEM 編碼的私鑰
範例
$ca := buildCustomCert "base64-encoded-ca-crt" "base64-encoded-ca-key"
請注意,傳回的物件可以傳遞給 genSignedCert
函數,以使用此 CA 簽署憑證。
genCA
genCA
函數會產生一個新的、自我簽署的 x509 憑證授權單位。
它接受以下參數
- 主體的通用名稱 (cn)
- 憑證有效期(以天為單位)
它會傳回具有以下屬性的物件
Cert
:PEM 編碼的憑證Key
:PEM 編碼的私鑰
範例
$ca := genCA "foo-ca" 365
請注意,傳回的物件可以傳遞給 genSignedCert
函數,以使用此 CA 簽署憑證。
genSelfSignedCert
genSelfSignedCert
函數會產生一個新的、自我簽署的 x509 憑證。
它接受以下參數
- 主體的通用名稱 (cn)
- IP 的選用清單;可以為 nil
- 替代 DNS 名稱的選用清單;可以為 nil
- 憑證有效期(以天為單位)
它會傳回具有以下屬性的物件
Cert
:PEM 編碼的憑證Key
:PEM 編碼的私鑰
範例
$cert := genSelfSignedCert "foo.com" (list "10.0.0.1" "10.0.0.2") (list "bar.com" "bat.com") 365
genSignedCert
genSignedCert
函數會產生一個新的、由指定 CA 簽署的 x509 憑證。
它接受以下參數
- 主體的通用名稱 (cn)
- IP 的選用清單;可以為 nil
- 替代 DNS 名稱的選用清單;可以為 nil
- 憑證有效期(以天為單位)
- CA(參見
genCA
)
範例
$ca := genCA "foo-ca" 365
$cert := genSignedCert "foo.com" (list "10.0.0.1" "10.0.0.2") (list "bar.com" "bat.com") 365 $ca
encryptAES
encryptAES
函數使用 AES-256 CBC 加密文字,並傳回以 Base64 編碼的字串。
encryptAES "secretkey" "plaintext"
decryptAES
decryptAES
函數接收由 AES-256 CBC 演算法編碼的 Base64 字串,並傳回解碼的文字。
"30tEfhuJSVRhpG97XCuWgz2okj7L8vQ1s6V9zVUPeDQ=" | decryptAES "secretkey"
日期函數
Helm 包含以下您可以在範本中使用的日期函數:ago、date、dateInZone、dateModify (mustDateModify)、duration、durationRound、htmlDate、htmlDateInZone、now、toDate (mustToDate) 和 unixEpoch。
now
目前的日期/時間。將此與其他日期函數一起使用。
ago
ago
函數傳回從時間開始的持續時間。現在以秒解析度。
ago .CreatedAt
以 time.Duration
String() 格式傳回
2h34m7s
date
date
函數格式化日期。
將日期格式化為 年-月-日
now | date "2006-01-02"
Go 中的日期格式化 略有不同。
簡而言之,將此作為基準日期
Mon Jan 2 15:04:05 MST 2006
以您想要的格式編寫。以上,2006-01-02
是同一天,但採用我們想要的格式。
dateInZone
與 date
相同,但帶有時區。
dateInZone "2006-01-02" (now) "UTC"
duration
將給定的秒數格式化為 time.Duration
。
這會傳回 1 分 35 秒
duration 95
durationRound
將給定的持續時間四捨五入到最重要的單位。字串和 time.Duration
會被解析為持續時間,而 time.Time
則會計算為自該時間以來的持續時間。
這會傳回 2 小時
durationRound "2h10m5s"
這會傳回 3 個月
durationRound "2400h10m5s"
unixEpoch
傳回自 Unix 紀元以來 time.Time
的秒數。
now | unixEpoch
dateModify, mustDateModify
dateModify
接受修改和日期,並傳回時間戳記。
從目前時間減去一小時三十秒
now | dateModify "-1.5h"
如果修改格式錯誤,dateModify
將傳回未修改的日期。否則,mustDateModify
將傳回錯誤。
htmlDate
htmlDate
函數格式化日期,以插入 HTML 日期選擇器輸入欄位。
now | htmlDate
htmlDateInZone
與 htmlDate 相同,但帶有時區。
htmlDateInZone (now) "UTC"
toDate, mustToDate
toDate
將字串轉換為日期。第一個參數是日期佈局,第二個參數是日期字串。如果字串無法轉換,它會傳回零值。如果字串無法轉換,mustToDate
將傳回錯誤。
當您想要將字串日期轉換為另一種格式(使用管道)時,這很有用。以下範例將「2017-12-31」轉換為「31/12/2017」。
toDate "2006-01-02" "2017-12-31" | date "02/01/2006"
字典和字典函數
Helm 提供了一種稱為 dict
(「dictionary」的縮寫,如同 Python 中的用法)的鍵/值儲存類型。dict
是一種*無序*類型。
字典的鍵*必須是字串*。但是,值可以是任何類型,甚至是另一個 dict
或 list
。
與 list
不同,dict
不是不可變的。set
和 unset
函數將修改字典的內容。
Helm 提供以下函數來支援使用字典:deepCopy (mustDeepCopy)、dict、dig、get、hasKey、keys、merge (mustMerge)、mergeOverwrite (mustMergeOverwrite)、omit、pick、pluck、set、unset 和 values。
dict
建立字典是透過呼叫 dict
函數並傳遞一對清單來完成的。
以下建立一個包含三個項目的字典
$myDict := dict "name1" "value1" "name2" "value2" "name3" "value 3"
get
給定一個映射和一個鍵,從映射中取得值。
get $myDict "name1"
以上傳回 "value1"
請注意,如果找不到鍵,此操作將只傳回 ""
。不會產生任何錯誤。
set
使用 set
將新的鍵/值對新增到字典中。
$_ := set $myDict "name4" "value4"
請注意,set
*會傳回字典*(Go 範本函數的要求),因此您可能需要像上面使用 $_
指派一樣擷取值。
unset
給定一個映射和一個鍵,從映射中刪除鍵。
$_ := unset $myDict "name4"
與 set
一樣,這會傳回字典。
請注意,如果找不到鍵,此操作將只傳回。不會產生任何錯誤。
hasKey
如果給定的字典包含給定的鍵,則 hasKey
函數會傳回 true
。
hasKey $myDict "name1"
如果找不到鍵,則傳回 false
。
pluck
pluck
函數可以提供一個鍵和多個映射,並取得所有符合項目的清單
pluck "name1" $myDict $myOtherDict
以上將傳回一個包含每個找到的值的 list
([value1 otherValue1]
)。
如果在映射中*找不到*給定的鍵,則該映射在清單中將沒有項目(且傳回清單的長度將小於 pluck
呼叫中的字典數)。
如果*找到*鍵但值是空值,則會插入該值。
Helm 範本中的一個常見用法是使用 pluck... | first
從字典集合中取得第一個符合的鍵。
dig
dig
函數遍歷巢狀的字典集,從值清單中選擇鍵。如果在關聯的字典中找不到任何鍵,它會傳回預設值。
dig "user" "role" "humanName" "guest" $dict
給定一個結構如下的字典
{
user: {
role: {
humanName: "curator"
}
}
}
以上將傳回 "curator"
。如果字典甚至缺少 user
欄位,則結果將是 "guest"
。
在您想要避免防禦子句的情況下,Dig 非常有用,尤其是在 Go 的範本套件的 and
不會捷徑的情況下。例如,and a.maybeNil a.maybeNil.iNeedThis
將始終評估 a.maybeNil.iNeedThis
,如果 a
缺少 maybeNil
欄位,則會發生恐慌。)
dig
接受其字典參數最後,以支援管道。例如
merge a b c | dig "one" "two" "three" "<missing>"
merge, mustMerge
將兩個或多個字典合併成一個,優先考慮目標字典
給定
dst:
default: default
overwrite: me
key: true
src:
overwrite: overwritten
key: false
將導致
newdict:
default: default
overwrite: me
key: true
$newdict := merge $dest $source1 $source2
這是一個深層合併操作,但不是深層複製操作。合併的巢狀物件在兩個字典上是相同的實例。如果您想要深層複製以及合併,則將 deepCopy
函數與合併一起使用。例如,
deepCopy $source | merge $dest
如果合併失敗,mustMerge
將傳回錯誤。
mergeOverwrite, mustMergeOverwrite
將兩個或多個字典合併成一個,優先順序從*右到左*,有效地覆蓋目標字典中的值
給定
dst:
default: default
overwrite: me
key: true
src:
overwrite: overwritten
key: false
將導致
newdict:
default: default
overwrite: overwritten
key: false
$newdict := mergeOverwrite $dest $source1 $source2
這是一個深層合併操作,但不是深層複製操作。合併的巢狀物件在兩個字典上是相同的實例。如果您想要深層複製以及合併,則將 deepCopy
函數與合併一起使用。例如,
deepCopy $source | mergeOverwrite $dest
如果合併失敗,mustMergeOverwrite
將傳回錯誤。
keys
keys
函數將傳回一個或多個 dict
類型中所有鍵的 list
。由於字典是*無序的*,因此鍵的順序將無法預測。它們可以使用 sortAlpha
進行排序。
keys $myDict | sortAlpha
當提供多個字典時,鍵將被串連。將 uniq
函數與 sortAlpha
一起使用,以取得唯一、排序的鍵清單。
keys $myDict $myOtherDict | uniq | sortAlpha
pick
pick
函數只從字典中選擇給定的鍵,建立一個新的 dict
。
$new := pick $myDict "name1" "name2"
以上傳回 {name1: value1, name2: value2}
omit
omit
函數類似於 pick
,不同之處在於它傳回一個新的 dict
,其中包含所有*不*符合給定鍵的鍵。
$new := omit $myDict "name1" "name3"
以上傳回 {name2: value2}
values
values
函數類似於 keys
,不同之處在於它傳回一個新的 list
,其中包含來源 dict
的所有值(僅支援一個字典)。
$vals := values $myDict
以上傳回 list["value1", "value2", "value 3"]
。請注意,values
函數不保證結果順序;如果您關心這個問題,則使用 sortAlpha
。
deepCopy, mustDeepCopy
deepCopy
和 mustDeepCopy
函數會取得一個值,並製作該值的深層副本。這包括字典和其他結構。當出現問題時,deepCopy
會發生恐慌,而 mustDeepCopy
會在出現錯誤時將錯誤傳回範本系統。
dict "a" 1 "b" 2 | deepCopy
關於字典內部的注意事項
dict
在 Go 中實作為 map[string]interface{}
。Go 開發人員可以將 map[string]interface{}
值傳遞到上下文中,以使其作為 dict
可供範本使用。
編碼函數
Helm 具有以下編碼和解碼函數
b64enc
/b64dec
:使用 Base64 編碼或解碼b32enc
/b32dec
:使用 Base32 編碼或解碼
清單和清單函數
Helm 提供了一個簡單的 list
類型,可以包含任意順序的資料清單。這類似於陣列或切片,但清單設計用於作為不可變的資料類型。
建立一個整數清單
$myList := list 1 2 3 4 5
以上程式碼會建立一個 [1 2 3 4 5]
的列表。
Helm 提供以下列表函數:append (mustAppend)、compact (mustCompact)、concat、first (mustFirst)、has (mustHas)、initial (mustInitial)、last (mustLast)、prepend (mustPrepend)、rest (mustRest)、reverse (mustReverse)、seq、index、slice (mustSlice)、uniq (mustUniq)、until、untilStep 和 without (mustWithout)。
first, mustFirst
要取得列表的第一個項目,請使用 first
。
first $myList
會回傳 1
如果發生問題,first
會發生 panic,而 mustFirst
會將錯誤回傳給模板引擎。
rest, mustRest
要取得列表的尾部(除了第一個項目以外的所有項目),請使用 rest
。
rest $myList
會回傳 [2 3 4 5]
如果發生問題,rest
會發生 panic,而 mustRest
會將錯誤回傳給模板引擎。
last, mustLast
要取得列表的最後一個項目,請使用 last
last $myList
會回傳 5
。這大致類似於反轉列表,然後呼叫 first
。
initial, mustInitial
這與 last
互補,會回傳除了最後一個元素以外的所有元素。initial $myList
會回傳 [1 2 3 4]
。
如果發生問題,initial
會發生 panic,而 mustInitial
會將錯誤回傳給模板引擎。
append, mustAppend
將新項目附加到現有列表,建立新的列表。
$new = append $myList 6
以上程式碼會將 $new
設定為 [1 2 3 4 5 6]
。$myList
將保持不變。
如果發生問題,append
會發生 panic,而 mustAppend
會將錯誤回傳給模板引擎。
prepend, mustPrepend
將元素推送到列表的前面,建立新的列表。
prepend $myList 0
以上程式碼會產生 [0 1 2 3 4 5]
。$myList
將保持不變。
如果發生問題,prepend
會發生 panic,而 mustPrepend
會將錯誤回傳給模板引擎。
concat
將任意數量的列表串接成一個。
concat $myList ( list 6 7 ) ( list 8 )
以上程式碼會產生 [1 2 3 4 5 6 7 8]
。$myList
將保持不變。
reverse, mustReverse
產生一個新的列表,其中包含給定列表的反轉元素。
reverse $myList
以上程式碼會產生列表 [5 4 3 2 1]
。
如果發生問題,reverse
會發生 panic,而 mustReverse
會將錯誤回傳給模板引擎。
uniq, mustUniq
產生一個已移除所有重複項的列表。
list 1 1 1 2 | uniq
以上程式碼會產生 [1 2]
如果發生問題,uniq
會發生 panic,而 mustUniq
會將錯誤回傳給模板引擎。
without, mustWithout
without
函數會從列表中篩選掉項目。
without $myList 3
以上程式碼會產生 [1 2 4 5]
without
可以採用多個篩選器
without $myList 1 3 5
這會產生 [2 4]
如果發生問題,without
會發生 panic,而 mustWithout
會將錯誤回傳給模板引擎。
has, mustHas
測試列表是否具有特定元素。
has 4 $myList
以上程式碼會回傳 true
,而 has "hello" $myList
會回傳 false。
如果發生問題,has
會發生 panic,而 mustHas
會將錯誤回傳給模板引擎。
compact, mustCompact
接受一個列表,並移除具有空值的項目。
$list := list 1 "a" "foo" ""
$copy := compact $list
compact
會回傳一個新的列表,其中已移除空的(即 "")項目。
如果發生問題,compact
會發生 panic,而 mustCompact
會將錯誤回傳給模板引擎。
index
要取得列表的第 n 個元素,請使用 index list [n]
。要索引多維列表,請使用 index list [n] [m] ...
index $myList 0
會回傳1
。這與myList[0]
相同index $myList 0 1
會與myList[0][1]
相同
slice, mustSlice
要取得列表的部分元素,請使用 slice list [n] [m]
。這相當於 list[n:m]
。
slice $myList
會回傳[1 2 3 4 5]
。這與myList[:]
相同。slice $myList 3
會回傳[4 5]
。這與myList[3:]
相同。slice $myList 1 3
會回傳[2 3]
。這與myList[1:3]
相同。slice $myList 0 3
會回傳[1 2 3]
。這與myList[:3]
相同。
如果發生問題,slice
會發生 panic,而 mustSlice
會將錯誤回傳給模板引擎。
until
until
函數會建立一個整數範圍。
until 5
以上程式碼會產生列表 [0, 1, 2, 3, 4]
。
這對於使用 range $i, $e := until 5
進行迴圈很有用。
untilStep
與 until
類似,untilStep
會產生一個計數整數列表。但它允許您定義起始值、結束值和步長
untilStep 3 6 2
以上程式碼會從 3 開始,並加上 2 直到等於或大於 6,從而產生 [3 5]
。這類似於 Python 的 range
函數。
seq
作用類似於 bash 的 seq
命令。
- 1 個參數(結束值) - 會產生 1 到
結束值
之間(含)的所有計數整數。 - 2 個參數(起始值、結束值) - 會產生
起始值
到結束值
之間(含)的所有計數整數,以 1遞增或遞減。 - 3 個參數(起始值、步長、結束值) - 會產生
起始值
到結束值
之間(含)的所有計數整數,以步長
遞增或遞減。
seq 5 => 1 2 3 4 5
seq -3 => 1 0 -1 -2 -3
seq 0 2 => 0 1 2
seq 2 -2 => 2 1 0 -1 -2
seq 0 2 10 => 0 2 4 6 8 10
seq 0 -2 -5 => 0 -2 -4
數學函數
除非另有說明,否則所有數學函數都對 int64
值進行運算。
以下數學函數可用:add、add1、ceil、div、floor、len、max、min、mod、mul、round 和 sub。
add
使用 add
對數字求和。接受兩個或多個輸入。
add 1 2 3
add1
要遞增 1,請使用 add1
。
sub
要進行減法,請使用 sub
。
div
使用 div
執行整數除法。
mod
使用 mod
進行模數運算。
mul
使用 mul
進行乘法。接受兩個或多個輸入。
mul 1 2 3
max
回傳一系列整數中的最大值。
這會回傳 3
max 1 2 3
min
回傳一系列整數中的最小值。
min 1 2 3
會回傳 1
。
len
以整數形式回傳參數的長度。
len .Arg
浮點數數學函數
所有數學函數都對 float64
值進行運算。
addf
使用 addf
對數字求和
這會回傳 5.5
addf 1.5 2 2
add1f
要遞增 1,請使用 add1f
subf
要進行減法,請使用 subf
這相當於 7.5 - 2 - 3
,並且會回傳 2.5
subf 7.5 2 3
divf
使用 divf
執行整數除法
這相當於 10 / 2 / 4
,並且會回傳 1.25
divf 10 2 4
mulf
使用 mulf
進行乘法
這會回傳 6
mulf 1.5 2 2
maxf
回傳一系列浮點數中的最大值
這會回傳 3
maxf 1 2.5 3
minf
回傳一系列浮點數中的最小值。
這會回傳 1.5
minf 1.5 2 3
floor
回傳小於或等於輸入值的最大的浮點數值。
floor 123.9999
會回傳 123.0
。
ceil
回傳大於或等於輸入值的最大的浮點數值。
ceil 123.001
會回傳 124.0
。
round
回傳一個浮點數值,其餘數四捨五入到小數點後給定數量的位數。
round 123.555555 3
會回傳 123.556
。
網路函數
Helm 有一個網路函數,getHostByName
。
getHostByName
接收網域名稱,並回傳 IP 位址。
getHostByName "www.google.com"
會回傳 www.google.com
的對應 IP 位址。
檔案路徑函數
雖然 Helm 模板函數不允許存取檔案系統,但它們確實提供了用於處理遵循檔案路徑慣例的字串的函數。這些函數包括 base、clean、dir、ext 和 isAbs。
base
回傳路徑的最後一個元素。
base "foo/bar/baz"
以上程式碼會印出 "baz"。
dir
回傳目錄,去除路徑的最後一部分。因此 dir "foo/bar/baz"
會回傳 foo/bar
。
clean
清理路徑。
clean "foo/bar/../baz"
以上程式碼會解析 ..
並回傳 foo/baz
。
ext
回傳檔案副檔名。
ext "foo.bar"
以上程式碼會回傳 .bar
。
isAbs
要檢查檔案路徑是否為絕對路徑,請使用 isAbs
。
反射函數
Helm 提供基本的反射工具。這些工具可以幫助進階模板開發人員了解特定值的底層 Go 類型資訊。Helm 是用 Go 編寫的,並且是強類型的。類型系統適用於模板內。
Go 有幾種基本的*種類*,例如 string
、slice
、int64
和 bool
。
Go 有一個開放的*類型*系統,允許開發人員建立自己的類型。
Helm 通過 種類函數 和 類型函數 為每個種類和類型提供一組函數。還提供了一個 deepEqual 函數來比較兩個值。
種類函數
有兩個種類函數:kindOf
會回傳物件的種類。
kindOf "hello"
以上程式碼會回傳 string
。對於簡單的測試(例如在 if
區塊中),kindIs
函數可以讓您驗證值是否為特定種類
kindIs "int" 123
以上程式碼會回傳 true
。
類型函數
類型稍微難以處理,因此有三個不同的函數
typeOf
會回傳值的底層類型:typeOf $foo
typeIs
類似於kindIs
,但適用於類型:typeIs "*io.Buffer" $myVal
typeIsLike
的作用與typeIs
相同,但它還會取消指標的引用
**注意:**這些函數都無法測試某個東西是否實作了給定的介面,因為這樣做需要事先編譯介面。
deepEqual
如果兩個值 "深度相等",則 deepEqual
會回傳 true
也適用於非基本類型(與內建的 eq
相比)。
deepEqual (list 1 2 3) (list 1 2 3)
以上程式碼會回傳 true
。
語義版本函數
有些版本方案很容易解析和比較。Helm 提供了用於處理 SemVer 2 版本的函數。這些函數包括 semver 和 semverCompare。您還可以在下面找到有關使用範圍進行比較的詳細資訊。
semver
semver
函數會將字串解析為語義版本
$version := semver "1.2.3-alpha.1+123"
如果解析失敗,它將導致模板執行停止並出現錯誤。
此時,$version
是一個指向具有以下屬性的 Version
物件的指標
$version.Major
:主要版本號(以上為1
)$version.Minor
:次要版本號(以上為2
)$version.Patch
:修補版本號(以上為3
)$version.Prerelease
:預發布版本(以上為alpha.1
)$version.Metadata
:建置中繼資料(以上為123
)$version.Original
:原始版本,以字串表示
此外,您可以使用 Compare
函數將 Version
與另一個 version
進行比較
semver "1.4.3" | (semver "1.2.3").Compare
以上程式碼會回傳 -1
。
回傳值如下
- 如果給定的語意化版本大於呼叫其 `Compare` 方法的語意化版本,則傳回 `-1`
- 如果呼叫 `Compare` 函數的版本較大,則傳回 `1`。
- 如果它們是相同的版本,則傳回 `0`
(請注意,在語意化版本中,`Metadata` 欄位在版本比較操作期間不會被比較。)
semverCompare
一個更強大的比較函數以 `semverCompare` 的形式提供。此版本支援版本範圍
- `semverCompare "1.2.3" "1.2.3"` 檢查是否完全匹配
- `semverCompare "~1.2.0" "1.2.3"` 檢查主版本和次版本是否匹配,以及第二個版本的修訂號是否 *大於或等於* 第一個參數。
SemVer 函數使用 Sprig 的創建者所開發的 Masterminds semver 函式庫。
基本比較
比較有兩個要素。首先,比較字串是由空格或逗號分隔的 AND 比較所組成的列表。然後這些比較會由 ||(OR)分隔。例如,`">= 1.2 < 3.0.0 || >= 4.2.3"` 正在尋找大於或等於 1.2 且小於 3.0.0 或大於或等於 4.2.3 的比較。
基本比較如下
- `=`:等於(別名為無運算符)
- `!=`:不等於
- `>`:大於
- `<`:小於
- `>=`:大於或等於
- `<=`:小於或等於
處理預發佈版本
預發佈版本,對於不熟悉的人來說,是用於穩定或正式發行版本之前的軟體發行版本。預發佈版本的例子包括開發版、Alpha 版、Beta 版和候選發行版。預發佈版本可能是 `1.2.3-beta.1` 之類的版本,而穩定版本則是 `1.2.3`。在優先順序上,預發佈版本排在其相關發行版本之前。在此範例中,`1.2.3-beta.1 < 1.2.3`。
根據語意化版本規範,預發佈版本可能與其發行版本不符合 API 規範。它指出:
預發佈版本表示該版本不穩定,並且可能不滿足其關聯的正式版本所表示的預期相容性要求。
使用沒有預發佈版本比較器的約束條件進行 SemVer 比較將會跳過預發佈版本。例如,`>=1.2.3` 在查看發行版本列表時將會跳過預發佈版本,而 `>=1.2.3-0` 將會評估並找到預發佈版本。
範例比較中使用 `0` 作為預發佈版本的原因是,根據規範,預發佈版本只能包含 ASCII 英數字和連字符(以及 `.` 分隔符號)。排序按照 ASCII 排序順序進行,同樣根據規範。在 ASCII 排序順序中,最低的字元是 `0`(請參閱 ASCII 表)
了解 ASCII 排序順序很重要,因為 A-Z 排在 a-z 之前。這表示 `>=1.2.3-BETA` 將會傳回 `1.2.3-alpha`。您可能期望的大小寫敏感性在這裡不適用。這是由於 ASCII 排序順序是規範所指定的。
連字符範圍比較
有多種方法可以處理範圍,第一種是連字符範圍。它們看起來像這樣
- `1.2 - 1.4.5` 等同於 `>= 1.2 <= 1.4.5`
- `2.3.4 - 4.5` 等同於 `>= 2.3.4 <= 4.5`
比較中的萬用字元
`x`、`X` 和 `*` 字元可以用作萬用字元。這適用於所有比較運算符。當用於 `=` 運算符時,它會回到修訂號比較(請參閱下方的波浪號)。例如:
- `1.2.x` 等同於 `>= 1.2.0, < 1.3.0`
- `>= 1.2.x` 等同於 `>= 1.2.0`
- `<= 2.x` 等同於 `< 3`
- `*` 等同於 `>= 0.0.0`
波浪號範圍比較(修訂號)
波浪號 (`~`) 比較運算符用於指定次版本時的修訂號範圍,以及缺少次版本號時的主版本號變更。例如:
- `~1.2.3` 等同於 `>= 1.2.3, < 1.3.0`
- `~1` 等同於 `>= 1, < 2`
- `~2.3` 等同於 `>= 2.3, < 2.4`
- `~1.2.x` 等同於 `>= 1.2.0, < 1.3.0`
- `~1.x` 等同於 `>= 1, < 2`
插入符號範圍比較(主版本號)
插入符號 (`^`) 比較運算符用於在穩定版(1.0.0)發行之後的主版本號變更。在 1.0.0 版本之前,次版本號充當 API 穩定性級別。這在比較 API 版本時很有用,因為主版本號變更會破壞 API。例如:
- `^1.2.3` 等同於 `>= 1.2.3, < 2.0.0`
- `^1.2.x` 等同於 `>= 1.2.0, < 2.0.0`
- `^2.3` 等同於 `>= 2.3, < 3`
- `^2.x` 等同於 `>= 2.0.0, < 3`
- `^0.2.3` 等同於 `>=0.2.3 <0.3.0`
- `^0.2` 等同於 `>=0.2.0 <0.3.0`
- `^0.0.3` 等同於 `>=0.0.3 <0.0.4`
- `^0.0` 等同於 `>=0.0.0 <0.1.0`
- `^0` 等同於 `>=0.0.0 <1.0.0`
URL 函數
Helm 包括 urlParse、urlJoin 和 urlquery 函數,讓您可以處理 URL 部分。
urlParse
解析字串中的 URL 並產生包含 URL 部分的字典
urlParse "http://admin:secret@server.com:8080/api?list=false#anchor"
以上傳回一個字典,包含 URL 物件
scheme: 'http'
host: 'server.com:8080'
path: '/api'
query: 'list=false'
opaque: nil
fragment: 'anchor'
userinfo: 'admin:secret'
這是使用 Go 標準函式庫中的 URL 套件實作的。如需更多資訊,請查看 https://go.dev.org.tw/pkg/net/url/#URL
urlJoin
合併地圖(由 `urlParse` 產生)以產生 URL 字串
urlJoin (dict "fragment" "fragment" "host" "host:80" "path" "/path" "query" "query" "scheme" "http")
以上傳回以下字串
http://host:80/path?query#fragment
urlquery
傳回作為參數傳入的值的跳脫版本,以便適合嵌入 URL 的查詢部分。
$var := urlquery "string for query"
UUID 函數
Helm 可以產生 UUID v4 通用唯一 ID。
uuidv4
以上傳回一個新的 v4 類型(隨機產生)的 UUID。
Kubernetes 和 Chart 函數
Helm 包括用於處理 Kubernetes 的函數,包括 .Capabilities.APIVersions.Has、檔案 和 lookup。
lookup
`lookup` 用於在正在執行的叢集中查找資源。與 `helm template` 命令一起使用時,它總是傳回空的回應。
您可以在 lookup 函數的說明文件中 找到更多詳細資訊。
.Capabilities.APIVersions.Has
傳回叢集中是否可以使用 API 版本或資源。
.Capabilities.APIVersions.Has "apps/v1"
.Capabilities.APIVersions.Has "apps/v1/Deployment"
更多資訊可在 內建物件說明文件 中找到。
檔案函數
有幾個函數讓您可以存取 Chart 中的非特殊檔案。例如,存取應用程式設定檔。這些函數在 存取範本中的檔案 中有說明。
請注意,其中許多函數的說明文件來自 Sprig。Sprig 是一個 Go 應用程式可用的範本函數庫。