All functions in templateManager
accept their principle argument last to allow simple chaining. Efforts have been made to output clear errors and return suitable empty values rather than cause panics (a problem in several text/template
functions).
Contents: add
, bool
, capfirst
, collection
, concat
, contains
, cut
, date
, datetime
, default
, divide
, divideceil
, dividefloor
, divisibleby
, dl
, endswith
, equal
, first
, firstof
, float
, formattime
, gto
, gte
, htmldecode
, htmlencode
, int
, iterable
, join
, jsondecode
, jsonencode
, key
, keys
, kind
, last
, length
, list
, lto
, lte
, localtime
, lower
, lpad
, ltrim
, md5
, mktime
, multiply
, nl2br
, notequal
, now
, ol
, ordinal
, paragraph
, pluralise
, prefix
, query
, random
, regexp
, regexpreplace
, render
, replace
, round
, rpad
, rtrim
, sha1
, sha256
, sha512
, split
, startswith
, string
, striptags
, substr
, subtract
, suffix
, time
, timesince
, timeuntil
, title
, trim
, truncate
, truncatewords
, type
, ul
, upper
, urldecode
, urlencode
, uuid
, values
, wordcount
, wrap
, year
, yesno
func add[T any](add T, to T) T
Adds a value to the existing item. If the added value is a simple numeric type, this will be treated as a simple addition using floats and applying rounding for integers (recursively on all possible items). If the added value is a string, it will be appended to string values as a suffix (recursively on all possible items). If the added value is a more complex type (e.g. slice / map), then it is appended / merged as appropriate in a similar manner to Django's add function. Unsupported types (e.g. booleans and structs are ignored and passed through).
Returns new variable of the original to
data type.
<!-- Integers: .Test is 10 -->
{{ add 25 .Test }} <!-- 35 -->
{{ add -30 .Test }} <!-- -20 -->
{{ add 2.5 .Test }} <!-- 13 -->
{{ add 2.4 .Test }} <!-- 12 -->
{{ add "5" .Test }} <!-- 15 -->
{{ add "5.5" .Test }} <!-- 16 -->
{{ add "string" .Test }} <!-- 10 -->
{{ add .Test "string" }} <!-- string -->
<!-- Floats: .Test is 10.0 -->
{{ add 25 .Test }} <!-- 35.0 -->
{{ add -30 .Test }} <!-- -20.0 -->
{{ add 2.5 .Test }} <!-- 12.5 -->
{{ add 2.4 .Test }} <!-- 12.4 -->
{{ add "5" .Test }} <!-- 15.0 -->
{{ add "5.5" .Test }} <!-- 15.5 -->
{{ add "string" .Test }} <!-- 10.0 -->
{{ add .Test "string" }} <!-- string -->
<!-- Strings: .Test is "test" -->
{{ add 25 .Test }} <!-- test -->
{{ add "5" .Test }} <!-- test5 -->
{{ add "5.5" .Test }} <!-- test5.5 -->
{{ add "string" .Test }} <!-- teststring -->
{{ add .Test "string" }} <!-- stringtest -->
<!-- Recursive Slices / Arrays: .Test is [1, 2, 3] -->
{{ add 25 .Test }} <!-- [26, 27, 28] (see Integers for examples) -->
{{ add "string" .Test }} <!-- [1, 2, 3] -->
<!-- Recursive Slices / Arrays: .Test is ["string", "slice"] -->
{{ add "test" .Test }} <!-- ["stringtest", "slicetest"] -->
<!-- APPEND - slices / arrays must be of the same type as added element -->
<!-- Slices / Arrays: .Test is [1, 2, 3], .Add is [4, 5, 6] -->
{{ add .Add .Test }} <!-- [1, 2, 3, 4, 5, 6] -->
<!-- Slices / Arrays: .Test is ["string", "slice"], .Add is ["addition"] -->
{{ add .Add .Test }} <!-- ["string", "slice", "addition"] -->
<!-- Recursive Maps: .Test is ["first": 1, "second": 2] -->
{{ add 25 .Test }} <!-- ["first": 26, "second": 27] (see Integers for examples) -->
{{ add "string" .Test }} <!-- ["first": 1, "second": 2] -->
<!-- Recursive Maps: .Test is ["first": "one", "second": "two"] -->
{{ add "test" .Test }} <!-- ["first": "onetest", "second": "twotest"] -->
<!-- APPEND - map values must be of the same type as added element -->
<!-- Maps: .Test is ["first": 1, "second": 2], .Add is ["third": 3, "fourth": 4] -->
{{ add .Add .Test }} <!-- ["first": 1, "second": 2, "third": 3, "fourth": 4] -->
func bool(value any) bool
Attempts to convert any value
to a boolean. If this is impossible, the nil value (false) will be returned. Positive integers (> 0) and floats (>= 1) are treated as true, as are several string values: "true", "1", "yes", "y". More complex types area always false.
{{ bool "yes" }}
<!-- true -->
{{ bool 0 }}
<!-- false -->
{{ bool 1 }}
<!-- true -->
{{ bool 10 }}
<!-- true -->
{{ bool -1.23 }}
<!-- false -->
func capfirst[T any](value T) T
Capitalises the first letter of strings. Does not alter any other letters. If value
is a slice, array or map it will apply this conversion to any string elements that they contain, ignoring other types (passed through).
Returns a new variable of the original value
data type.
{{ capfirst "this string. has two sentences." }}
<!-- This string. has two sentences. -->
func collection(key1 string, value1 any, key2 string, value2 any, ...) map[string]any
Allows any number of pairs of keys / values to be grouped together into a map. This map can be passed to templates / blocks.
{{ template "partials/requiresMultipleVars.html" collection "var1" .Var1 "var2" .Var2 }}
func concat(values ...any) string
Concatenates any number of string-able values together in the order that they were declared.
{{ concat "first" "second" 3 4.567 }}
<!-- firstsecond34.567 -->
<!-- .Test is: []string{"test", "this"} -->
{{ concat "first" .Test "last" }}
<!-- firsttestthislast -->
func contains(find any, within any) bool
Determines whether the find
value is contained in the within
value. The find
value can act on strings, slices, arrays and maps, but contained types must match. For more complex types, the find
variable must match the whole value.
Returns a boolean value (always false for incompatible types).
{{ contains "test" "A string containing test" }} <!-- true -->
{{ contains "test" "A string containing Test" }} <!-- false -->
<!-- Slices / Arrays: .Test is ["hello world", "goodbye world"] -->
{{ contains "world" .Test }} <!-- false -->
{{ contains "hello world" .Test }} <!-- true -->
<!-- Maps: .Test is ["hello": "hello world", "world": "goodbye world"] -->
{{ contains "world" .Test }} <!-- false -->
{{ contains "hello world" .Test }} <!-- true -->
<!-- Structs: .Test is [name: "hello world", Name: "goodbye world"] -->
{{ contains "world" .Test }} <!-- false -->
{{ contains "hello world" .Test }} <!-- true -->
func cut[T any](remove string, from T) T
Will remove
a string value that is contained in the from
value. If from
is a slice, array or map it will apply this conversion to any string elements that they contain, ignoring other types (passed through).
Returns new variable of the original from
data type.
{{ cut "test" "A string containing test" }}
<!-- A string containing -->
{{ cut "test" "A string containing Test" }}
<!-- A string containing Test -->
<!-- Slices / Arrays: .Test is ["hello world", "goodbye world"] -->
{{ cut "world" .Test }}
<!-- ["hello ", "goodbye "] -->
{{ cut "hello world" .Test }}
<!-- ["", "goodbye world"] -->
<!-- Maps: .Test is ["hello": "hello world", "world": "goodbye world"] -->
{{ cut "world" .Test }}
<!-- ["hello": "hello", "world": "goodbye"] -->
{{ cut "hello world" .Test }}
<!-- ["hello": "", "world": "goodbye world"] -->
<!-- Structs: .Test is [name: "hello world", Name: "goodbye world"] -->
{{ cut "world" .Test }}
<!-- [name: "", Name: "goodbye"] -->
{{ cut "hello world" .Test }}
<!-- [name: "", Name: "goodbye world"] -->
func date(input ...any) string
Parses dates to return a simple date string (by default: "d/m/Y"). Supports Go, Python and PHP formatting standards (for input / output formatting). The last parameter is always the date input.
It can accept various parameter combinations:
<!-- Current date and default output format -->
{{ date }}
<!-- 13/10/2022 -->
<!-- Passed `time.Time` object (default output format) -->
{{ date .Time }}
<!-- 15/02/2020 -->
<!-- Passed Unix time (default output format) -->
{{ date 1556015421 }}
<!-- 23/04/2019 -->
<!-- Current date and Go formatting string -->
{{ date "02 Jan 2006" }}
<!-- 13 Oct 2022 -->
<!-- Current date and PHP formatting string -->
{{ date "d M Y" }}
<!-- 13 Oct 2022 -->
<!-- Passed Go formatting string and `time.Time` object -->
{{ date "02 Jan 2006" .Time }}
<!-- 15 Feb 2020 -->
<!-- Passed Go formatting string and Unix time -->
{{ date "02 Jan 2006" 1556015421 }}
<!-- 23 Apr 2019 -->
<!-- Passed Python formatting string and `time.RFC3339` string -->
{{ date "%d %b %Y" "2020-02-15T11:30:12Z" }}
<!-- 15 Feb 2020 -->
<!-- Passed defined output formatting string (MYSQL), defined input layout (ATOM) and matching date string -->
{{ date "MYSQL", "ATOM" "2020-02-15T11:30:12Z00:00" }}
<!-- 2020-02-15 11:30:12 -->
Date and time functions support various pre-defined formats for simplicity:
`ISO8601Z`: "X-m-d\\TH:i:sP", // "2006-01-02T15:04:05Z07:00"
`ISO8601`: "Y-m-d\\TH:i:sO", // "2006-01-02T15:04:05-07:00"
`RFC822Z`: "D, d M y H:i:s O", // "Mon, 02 Jan 06 15:04 -07:00"
`RFC822`: "D, d M y H:i:s T", // "Mon, 02 Jan 06 15:04 MST"
`RFC850`: "l, d-M-y H:i:s T", // "Monday, 02-Jan-06 15:04:05 MST"
`RFC1036`: "D, d M y H:i:s O", // "02 Jan 06 15:04 -07:00"
`RFC1123Z`: "D, d M Y H:i:s O", // "Mon, 02 Jan 2006 15:04:05 -07:00"
`RFC1123`: "D, d M Y H:i:s T", // "Mon, 02 Jan 2006 15:04:05 MST"
`RFC2822`: "D, d M Y H:i:s O", // "Mon, 02 Jan 2006 15:04:05 -07:00"
`RFC3339`: "Y-m-d\\TH:i:sP", // "2006-01-02T15:04:05Z07:00"
`W3C`: "Y-m-d\\TH:i:sP", // "2006-01-02T15:04:05Z07:00"
`ATOM`: "Y-m-d\\TH:i:sP", // "2006-01-02T15:04:05Z07:00"
`COOKIE`: "l, d-M-Y H:i:s T", // "Monday, 02-Jan-2006 15:04:05 MST"
`RSS`: "D, d M Y H:i:s O", // "Mon, 02 01 2006 15:04:05 -07:00"
`MYSQL`: "Y-m-d H:i:s", // "2006-01-02 15:04:05"
`UNIX`: "D M _j H:i:s T Y", // "Mon Jan _2 15:04:05 MST 2006"
`RUBY`: "D M d H:i:s o Y", // "Mon Jan 02 15:04:05 -0700 2006"
`ANSIC`: "D M _j H:i:s Y", // "Mon Jan _2 15:04:05 2006"
func datetime(input ...any) string
Parses dates to return a simple date and time string (by default: "d/m/Y H:i"). Supports Go, Python and PHP formatting standards (for input / output formatting). The last parameter is always the date input.
It can accept various parameter combinations:
<!-- Current date and default output format -->
{{ datetime }}
<!-- 13/10/2022 12:30 -->
<!-- Passed `time.Time` object (default output format) -->
{{ datetime .Time }}
<!-- 15/02/2020 11:30 -->
<!-- Passed Unix time (default output format) -->
{{ datetime 1556015421 }}
<!-- 23/04/2019 11:30 -->
<!-- Current date and Passed Go formatting string -->
{{ datetime "02 Jan 2006 15:04" }}
<!-- 13 Oct 2022 12:30 -->
<!-- Current date and PHP formatting string -->
{{ datetime "d M Y H:i" }}
<!-- 13 Oct 2022 12:30 -->
<!-- Passed Go formatting string and `time.Time` object -->
{{ datetime "02 Jan 2006 15:04" .Time }}
<!-- 15 Feb 2020 11:30 -->
<!-- Passed Go formatting string and Unix time -->
{{ datetime "02 Jan 2006 15:04" 1556015421 }}
<!-- 23 Apr 2019 11:30 -->
<!-- Passed Python formatting string and `time.RFC3339` string -->
{{ datetime "%d %b %Y %H:%M" "2020-02-15T11:30:12Z" }}
<!-- 15 Feb 2020 11:30 -->
<!-- Passed defined output formatting string (MYSQL), defined input layout (ATOM) and matching date string -->
{{ datetime "MYSQL", "ATOM" "2020-02-15T11:30:12Z00:00" }}
<!-- 2020-02-15 11:30:12 -->
Date and time functions support various pre-defined formats for simplicity, see date
.
func default(def any, test any) any
Will return the second test
value if it is not empty, else return the def
value.
{{ default "default" .Empty }} <!-- default -->
{{ default "default" "Not Empty" }} <!-- Not Empty -->
func divide[D int|float64, T any](divisor D, value T) T
Divides the value
by the divisor
. If value
is a slice, array or map it will apply this conversion to any numeric elements that they contain. All values are first converted to floats, the operation is performed and then any rounding is applied as necessary to return the item to its original type.
Returns a new variable of the original value
data type.
<!-- Integers: .Test is 10 -->
{{ divide 5 .Test }} <!-- 2 -->
{{ divide -5 .Test }} <!-- -2 -->
{{ divide 2.5 .Test }} <!-- 4 -->
{{ divide 2.4 .Test }} <!-- 4 -->
{{ divide 2.6 .Test }} <!-- 4 -->
{{ divide "5" .Test }} <!-- 2 -->
{{ divide "5.5" .Test }} <!-- 2 -->
{{ divide "string" .Test }} <!-- 10 -->
{{ divide .Test "string" }} <!-- string -->
<!-- Floats: .Test is 10.0 -->
{{ divide 5 .Test }} <!-- 2.0 -->
{{ divide -2 .Test }} <!-- -2.0 -->
{{ divide 2.5 .Test }} <!-- 4.0 -->
{{ divide 2.4 .Test }} <!-- 4.1666666 -->
{{ divide 2.6 .Test }} <!-- 3.8461538 -->
{{ divide "5" .Test }} <!-- 2.0 -->
{{ divide "5.5" .Test }} <!-- 1.81818181 -->
{{ divide "string" .Test }} <!-- 10.0 -->
{{ divide .Test "string" }} <!-- string -->
<!-- Slices / Arrays: .Test is [10, 20, 30] -->
{{ divide 2 .Test }} <!-- [5, 10, 15] (see above for examples) -->
{{ divide "string" .Test }} <!-- [10, 20, 30] -->
<!-- Maps: .Test is ["first": 10, "second": 20] -->
{{ divide 2 .Test }} <!-- ["first": 5, "second": 10] (see above for examples) -->
{{ divide "string" .Test }} <!-- ["first": 10, "second": 20] -->
func divideceil[D int|float64, T any](divisor D, value T) T
Divides the value
by the divisor
. If value
is a slice, array or map it will apply this conversion to any numeric elements that they contain. All values are first converted to floats, the operation is performed and then any rounding (ceil) is applied as necessary to return the item to its original type.
Returns a new variable of the original value
data type.
<!-- Integers: .Test is 10 -->
{{ divideceil 3 .Test }} <!-- 4 -->
See divide
for further examples.
func dividefloor[D int|float64, T any](divisor D, value T) T
Divides the value
by the divisor
. If value
is a slice, array or map it will apply this conversion to any numeric elements that they contain. All values are first converted to floats, the operation is performed and then any rounding (floor) is applied as necessary to return the item to its original type.
Returns a new variable of the original value
data type.
<!-- Integers: .Test is 10 -->
{{ dividefloor 4 .Test }} <!-- 2 -->
See divide
for further examples.
func divisibleby[T any](divisor int, value T) bool
Determines if the value
is exactly divisible by the divisor
. Non-numeric values return false.
{{ divisibleby 2 20 }} <!-- true -->
{{ divisibleby 2 19 }} <!-- false -->
{{ divisibleby 2.5 20 }} <!-- true -->
{{ divisibleby 2.6 20 }} <!-- false -->
{{ divisibleby 0.8 2.4 }} <!-- true -->
{{ divisibleby "2" 20 }} <!-- true -->
{{ divisibleby 2 "20" }} <!-- false -->
{{ divisibleby 2 true }} <!-- false -->
{{ divisibleby true 20 }} <!-- false -->
func dl(value any) string
Converts slices, arrays or maps into an HTML definition list. For maps this will use the keys as the dt elements.
Other data types will just return a string representation of themselves.
<!-- .Test is slice: [1, 2, 3] -->
{{ dl .Test }}
<!-- produces: -->
<dl>
<dd>1</dd>
<dd>2</dd>
<dd>3</dd>
</dl>
<!-- .Test is map: ["first": "first-content", "second": "second-content"] -->
{{ dl .Test }}
<!-- produces: -->
<dl>
<dt>first</dt>
<dd>first-content</dd>
<dt>second</dt>
<dd>second-content</dd>
</dl>
<!-- .Test is map: ["first": ["slice", "one"], "second": ["slice", "two"]] -->
{{ dl .Test }}
<!-- produces: -->
<dl>
<dt>first</dt>
<dd>
<dl>
<dd>slice</dd>
<dd>one</dd>
</dl>
</dd>
<dt>second</dt>
<dd>
<dl>
<dd>slice</dd>
<dd>two</dd>
</dl>
</dd>
</dl>
func endswith(find string, value string) bool
Tests whether a string value
ends with another string, find
. Returns false if either value is not a string.
{{ if endswith "fox" "the quick brown fox" }} ends with fox {{ end }}
<!-- ends with fox -->
<!-- OR more idiomatically... -->
{{ if "the quick brown fox" | endswith "fox" }} ends with fox {{ end }}
<!-- ends with fox -->
func equal(values ...any) bool
Tests whether any number of variables are equal. A safer alternative (no panics) for the text/template
eq
function. For numeric variables this is loose equality, in that types will be ignored (all values converted to float64
) and compared with a small tolerance. This function is not safe for very large uint64
values.
{{ equal "hello" "hello" }} <!-- true -->
{{ equal 1 1.0 }} <!-- true -->
{{ equal 1 1.0000000000001 }} <!-- true -->
{{ equal (divide 0.8 2.4) 3 }} <!-- true -->
{{ equal 1 1.0 1.0000000000001 }} <!-- true -->
{{ equal 1 1.0 1.0000000000002 }} <!-- false -->
<!-- .Test1 and .Test2 are both [1, 2, 3] -->
{{ equal .Test1 .Test2 }} <!-- true -->
(N.B. If OverloadFunctions()
has been used, this function will also replace the built in eq
function)
func first(value any) any
Gets the first value from slices / arrays or the first word from strings. All other data types return an empty variable.
{{ first "my test string" }} <!-- my -->
<!-- .Test is [1, 2, 3] -->
{{ first .Test }} <!-- 1 -->
func firstof(values ...any) any
Accepts any number of values and returns the first one of them that exists and is not empty. If none are found it returns an empty value.
{{ firstof .Empty .AlsoEmpty .NotEmpty }} <!-- .NotEmpty -->
{{ firstof .Empty "" 0 .NotEmpty .AlsoEmpty }} <!-- .NotEmpty -->
func float(value any) float64
Attempts to convert any value
to a float64. If this is impossible, the nil value (0.0) will be returned. More complex types are always 0.0.
{{ float "3" }}
<!-- 3.0 -->
{{ float 1 }}
<!-- 1.0 -->
{{ float true }}
<!-- 1.0 -->
{{ float -1.23 }}
<!-- -1.23 -->
func formattime(format string, t time.Time) string
Formats a time.Time object for display.
{{ now | formattime "d/m/y H:i:s" }}
Date and time functions support various pre-defined formats for simplicity, see date
.
func gto(value1 any, value2 any) bool
Determines if value2
is greater than value1
with loose numeric types. Only works on numeric types, anything else will return false. Arguments are reversed for pipelining.
{{ 2.4 | gto 2 }} <!-- true -->
{{ 2.4 | gto 2.4 }} <!-- false -->
<!-- Opposite to normal variable order for pipelining -->
{{ gto 2 2.4 }} <!-- true -->
{{ gto 2.4 2 }} <!-- false -->
(N.B. If OverloadFunctions()
has been used, this function will also replace the built in gt
function)
func gte(value1 any, value2 any) bool
Determines if value2
is greater than or equal to value1
with loose numeric types. Only works on numeric types, anything else will return false. Arguments are reversed for pipelining.
{{ 2.4 | gte 2 }} <!-- true -->
{{ 2.4 | gte 2.4 }} <!-- true -->
<!-- Opposite to normal variable order for pipelining -->
{{ gte 2 2.4 }} <!-- true -->
{{ gte 2.4 2 }} <!-- false -->
(N.B. If OverloadFunctions()
has been used, this function will also replace the built in ge
function)
func htmldecode[T any](value T) T
Converts HTML character-entity equivalents back into their literal, usable forms. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ htmldecode ""string" <strong>with</strong> 'html entities' &amp; other "nasty" stuff" }}
<!-- "string" <strong>with</strong> 'html entities' & other "nasty" stuff -->
func htmlencode[T any](value T) T
Converts literal HTML special characters into safe, character-entity equivalents. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ htmlencode `"string" <strong>with</strong> 'html entities' & other "nasty" stuff` }}
<!-- "string" <strong>with</strong> 'html entities' &amp; other "nasty" stuff -->
(N.B. If OverloadFunctions()
has been used, this function will also replace the built in html
function)
func int(value any) int
Attempts to convert any value
to an int. Floats will be rounded. If conversion is impossible, the nil value (0) will be returned. More complex types are always 0.
{{ int "3" }}
<!-- 3 -->
{{ int 1 }}
<!-- 1 -->
{{ int true }}
<!-- 1 -->
{{ int 4.67 }}
<!-- 5 -->
{{ int -1.23 }}
<!-- -1 -->
func iterable(options ...int) []int
There is no for
loop in the text/template
package, but one can be simulated using the range
function and an integer slice. The iterable
function allows a slice to be created for this purpose.
The possible options are best illustrated with examples:
<!-- for i := 0; i < 5; i++ -->
{{ range $i := iterable 5 }} {{ $i }} {{ end }}
<!-- for i := 3; i < 5; i++ -->
{{ range $i := iterable 3 5 }} {{ $i }} {{ end }}
<!-- for i := 3; i < 5; i += 2 -->
{{ range $i := iterable 3 5 2 }} {{ $i }} {{ end }}
func join(separator string, values any) string
Joins slice or map values
together as a string spaced by the separator
. Strings are returned unaltered and numeric types are coerced into strings. Maps are sorted alphabetically / numerically by their keys first for predictable results.
<!-- Slice / Array: .Test is [1, 2, 3] -->
{{ join "::" .Test }} <!-- 1::2::3 -->
<!-- Map: .Test is [2: "second", 1: "first"] -->
{{ join ", " .Test }} <!-- first, second -->
func jsondecode(value any) any
Decodes any JSON string to an interface{}
. This usually produces a type: map[string]any
, but may result in other types (e.g. []any
) or simple types (e.g. bool
, string
) for trivial data sources. ALL numbers will be float64
.
Use only with caution / testing.
func jsonencode(value any) string
Encodes any value to a JSON string.
<!-- .Test is map: ["first": ["slice", "one"], "second": ["slice", "two"]] -->
{{ jsonencode .Test }}
<!-- { "first": ["slice", "one"], "second": ["slice", "two"] } -->
func key(input ...any) any
Very similar to the in-built text/template
index
function, key
accepts any number of nested keys and returns the result of indexing its final argument by them. For strings this returns individual letters. The indexed item must be a string, map, slice, array or struct.
{{ key 2 "string" }} <!-- r -->
<!-- Slices / Arrays: .Test is ["first", "second", "third"] -->
{{ key 2 .Test }} <!-- third -->
{{ key 2 2 .Test }} <!-- i -->
{{ key 2 2 0 .Test }} <!-- i -->
{{ key 2 2 2 .Test }} <!-- -->
<!-- Maps: .Test is ["first": ["nested": "nested-value"]] -->
{{ key "first" .Test }} <!-- ["nested": "nested-value"] -->
{{ key "first" "nested" .Test }} <!-- nested-value -->
{{ key "first" "nested" 3 .Test }} <!-- t -->
(N.B. If OverloadFunctions()
has been used, this function will also replace the built in index
function)
func keys(value any) []any
Returns the keys of a slice / array / map / struct.
{{ keys .Slice }}
<!-- []int{0, 1, 2} -->
{{ keys .Map }}
<!-- []string{"key1", "key2", "key3"} -->
func kind(value any) string
Returns the value's reflect.Kind
as a string. Mainly useful for testing.
{{ kind 3.14159 }} <!-- float64 -->
{{ kind "test" }} <!-- string -->
<!-- Slice: .Test is []int{1, 2, 3} -->
{{ kind .Test }} <!-- slice -->
<!-- Array: .Test is [3]int{1, 2, 3} -->
{{ kind .Test }} <!-- array -->
<!-- Map: .Test is map[int]string{2: "second", 1: "first"} -->
{{ kind .Test }} <!-- map -->
func last(value any) any
Gets the last value from slices / arrays or the last word from strings. All other data types return an empty variable.
{{ last "my test string" }} <!-- string -->
<!-- .Test is [1, 2, 3] -->
{{ last .Test }} <!-- 3 -->
func length(value any) int
Gets length of any type. Unlike the text/template
function: len
, the length
function will work without panics on numeric types and booleans.
{{ length "my test string" }} <!-- 14 -->
{{ length 12 }} <!-- 2 -->
{{ length -3.14159 }} <!-- 8 -->
{{ length true }} <!-- 1 -->
<!-- .Test is [1, 2, 3] -->
{{ length .Test }} <!-- 3 -->
<!-- .Test is [1:"first", 2:"second"] -->
{{ length .Test }} <!-- 2 -->
(N.B. If OverloadFunctions()
has been used, this function will also replace the built in len
function)
func list(values ...any) []any
Accepts any number of arguments / types and returns a slice of interfaces that may be iterated over.
{{ $list := list 1 "string" true }}
<!-- [1, "string", true] -->
func lto(value1 any, value2 any) bool
Determines if value2
is less than value1
with loose numeric types. Only works on numeric types, anything else will return false. Arguments are reversed for pipelining.
{{ 2.4 | lto 3 }} <!-- true -->
{{ 2.4 | lto 2 }} <!-- false -->
{{ 2.4 | lto 2.4 }} <!-- false -->
<!-- Opposite to normal variable order for pipelining -->
{{ lto 2 2.4 }} <!-- false -->
{{ lto 2.4 2 }} <!-- true -->
(N.B. If OverloadFunctions()
has been used, this function will also replace the built in lt
function)
func lte(value1 any, value2 any) bool
Determines if value2
is less than or equal to value1
with loose numeric types. Only works on numeric types, anything else will return false. Arguments are reversed for pipelining.
{{ 2.4 | lte 3 }} <!-- true -->
{{ 2.4 | lte 2 }} <!-- false -->
{{ 2.4 | lte 2.4 }} <!-- true -->
<!-- Opposite to normal variable order for pipelining -->
{{ lte 2 2.4 }} <!-- false -->
{{ lte 2.4 2 }} <!-- true -->
(N.B. If OverloadFunctions()
has been used, this function will also replace the built in le
function)
func localtime(location string|time.Location, t time.Time) time.Time
Localises a time object to display local times / dates. Localisation strings are system dependant.
{{ now | localtime "PST" | formattime "d/m/y H:i:s" }}
Date and time functions support various pre-defined formats for simplicity, see date
.
func lower[T any](value T) T
Converts string text to lower case. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ lower "This string. Has TWO sentences." }}
<!-- this string. has two sentences. -->
func lpad[T any](length int, pad string, value T) T
Pads the left of a value
with the pad
string until value
is length
runes long. It will treat HTML entities as a single rune. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ lpad 10 "." "Test" }}
<!-- ......Test -->
{{ "Test" | lpad 9 " ." }}
<!-- . . . . .Test -->
func ltrim[T any](remove string, value T) T
Removes the passed characters from the left end of string values. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ ltrim " " " This string. Has TWO sentences." }}
<!-- This string. Has TWO sentences. -->
{{ ltrim " hT" " This string. Has TWO sentences." }}
<!-- is string. Has TWO sentences. -->
{{ ltrim "hT" " This string. Has TWO sentences." }}
<!-- This string. Has TWO sentences. -->
func md5(value any) string
The md5
function creates an MD5 hash for whatever variable is passed to it. Since hashing algorithms only accept strings, any other type of variable is first given a string value and then hashed.
{{ md5 "anything" }}
<!-- f0e166dc34d14d6c228ffac576c9a43c -->
func mktime(values ...any) time.Time
The mktime
function creates new time.Time
struct from simple time strings. Returns the current time if an invalid input is given. Supports Go, Python and PHP formatting standards.
It can accept various parameter combinations:
<!-- Current time -->
{{ mktime }}
<!-- Parse from a `time.RFC3339` string -->
{{ mktime "2020-02-15T11:30:12Z" }}
<!-- Parse from a custom Go layout string -->
{{ mktime "2006-01-02T15:04:05Z07:00", "2020-02-15T11:30:12Z00:00" }}
<!-- Parse from a custom PHP layout string -->
{{ mktime "Y-m-d\\TH:i:sP", "2020-02-15T11:30:12Z00:00" }}
<!-- Parse from a pre-defined layout string -->
{{ mktime "ATOM", "2020-02-15T11:30:12Z00:00" }}
Date and time functions support various pre-defined formats for simplicity, see date
.
func multiply[M int|float64, T any](multiplier M, value T) T
Multiplies the value
by the multiplier
. If value
is a slice, array or map it will apply this conversion to any numeric elements that they contain. All values are first converted to floats, the operation is performed and then any rounding is applied as necessary to return the item to its original type.
<!-- Integers: .Test is 10 -->
{{ multiply 5 .Test }} <!-- 50 -->
{{ multiply -5 .Test }} <!-- -50 -->
{{ multiply 2.5 .Test }} <!-- 25 -->
{{ multiply 2.4 .Test }} <!-- 24 -->
{{ multiply 2.6 .Test }} <!-- 26 -->
{{ multiply "5" .Test }} <!-- 50 -->
{{ multiply "5.5" .Test }} <!-- 55 -->
{{ multiply "string" .Test }} <!-- 10 -->
{{ multiply .Test "string" }} <!-- string -->
<!-- Floats: .Test is 10.0 -->
{{ multiply 5 .Test }} <!-- 50.0 -->
{{ multiply -5 .Test }} <!-- -50.0 -->
{{ multiply 2.5 .Test }} <!-- 25.0 -->
{{ multiply 2.4 .Test }} <!-- 24.0 -->
{{ multiply 2.6 .Test }} <!-- 26.0 -->
{{ multiply "5" .Test }} <!-- 50.0 -->
{{ multiply "5.5" .Test }} <!-- 55.0 -->
{{ multiply "string" .Test }} <!-- 10.0 -->
{{ multiply .Test "string" }} <!-- string -->
<!-- Slices / Arrays: .Test is [10, 20, 30] -->
{{ multiply 2 .Test }} <!-- [20, 40, 60] (see above for examples) -->
{{ multiply "string" .Test }} <!-- [10, 20, 30] -->
<!-- Maps: .Test is ["first": 10, "second": 20] -->
{{ multiply 2 .Test }} <!-- ["first": 20, "second": 40] (see above for examples) -->
{{ multiply "string" .Test }} <!-- ["first": 10, "second": 20] -->
func nl2br[T any](value T) T
Replaces all instances of \n
(new line) with instances of <br>
within value
. If value
is a slice, array or map it will apply this conversion to any string elements that they contain. paragraph
will perform a similar task in a more intelligent manner.
Returns a new variable of the original value
data type.
{{ nl2br "test\nstring" }} <!-- test<br>string -->
func notequal(values ...any) bool
Tests whether any number of variables are not equal. A safer alternative (no panics) for the text/template
neq
function. For numeric variables this is loose equality, in that types will be ignored (all values converted to float64
) and compared with a small tolerance. This function is not safe for very large uint64
values.
{{ notequal "hello" "hello" }} <!-- false -->
{{ notequal "hello" "Hello" }} <!-- true -->
{{ notequal 1 2 }} <!-- true -->
{{ notequal 1 1.0 }} <!-- false -->
{{ notequal 1 1.0000000000001 }} <!-- false -->
{{ notequal (divide 0.8 2.4) 3 }} <!-- false -->
{{ notequal 1 1.0 1.0000000000001 }} <!-- false -->
{{ notequal 1 1.0 1.0000000000002 }} <!-- true -->
<!-- .Test1 and .Test2 are both [1, 2, 3] -->
{{ notequal .Test1 .Test2 }} <!-- false -->
(N.B. If OverloadFunctions()
has been used, this function will also replace the built in ne
function)
func now() time.Time
Returns the current time.Time
value.
{{ now | localtime "PST" | formattime "d/m/y H:i:s" }}
func ol(value any) string
Converts slices, arrays or maps into an HTML ordered list.
Other data types will just return a string representation of themselves.
<!-- .Test is slice: [1, 2, 3] -->
{{ ol .Test }}
<!-- produces: -->
<ol>
<li>1</li>
<li>2</li>
<li>3</li>
</ol>
<!-- .Test is map: ["first": "first-content", "second": "second-content"] -->
{{ ol .Test }}
<!-- produces: -->
<ol>
<li>first-content</li>
<li>second-content</li>
</ol>
<!-- .Test is map: ["first": ["slice", "one"], "second": ["slice", "two"]] -->
{{ ol .Test }}
<!-- produces: -->
<ol>
<li>
<ol>
<li>slice</li>
<li>one</li>
</ol>
</li>
<li>
<ol>
<li>slice</li>
<li>two</li>
</ol>
</li>
</ol>
func ordinal[T int|float64|string](value T) string
Suffixes a number with the correct, English ordinal. If value
is not numeric or a valid numeric string, an empty string is returned.
{{ ordinal 1 }} <!-- 1st -->
{{ ordinal 112 }} <!-- 112th -->
{{ ordinal 1122 }} <!-- 1022nd -->
func paragraph[T any](value T) T
Replaces all string instances of \n+
(multiple new lines) with paragraph tags (</p><p>
) and instances of \n
(new line) with instances of <br>
within value
. Finally wraps the string in paragraph tags. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ paragraph "test\nstring" }} <!-- <p>test<br>string</p> -->
{{ paragraph "test\n\nstring" }} <!-- <p>test</p><p>string</p> -->
func pluralise(values ...any) string
Allows pluralisation of word endings. Allows basic customisation of the possible singular / plural forms. The default singular suffix is empty and the default plural suffix is "s".
It can accept various parameter combinations:
1 cat{{ pluralise 1 }}
<!-- 1 cat -->
2 cat{{ pluralise 2 }}
<!-- 2 cats -->
0 cat{{ pluralise 0 }}
<!-- 0 cats -->
1 mattress{{ pluralise "es" 1 }}
<!-- 1 mattress -->
2 mattress{{ pluralise "es" 2 }}
<!-- 2 mattresses -->
1 cherr{{ pluralise "y" "ies" 1 }}
<!-- 1 cherry -->
2 cherr{{ pluralise "y" "ies" 2 }}
<!-- 2 cherries -->
func prefix[T any](prefix ...string, value T) T
Prefixes all strings within value
with all strings within prefix
. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ prefix "prefix " "value" }} <!-- prefix value -->
{{ prefix "prefix1 " "prefix2 " "value" }} <!-- prefix1 prefix2 value -->
<!-- Slices / Arrays: .Test is ["string1", "string2"] -->
{{ prefix "prefix " .Test }}
<!-- ["prefix string1", "prefix string2"] -->
<!-- Maps: .Test is [1: "string1", 2: "string2"] -->
{{ prefix "prefix " .Test }}
<!-- [1: "prefix string1", 2: "prefix string2"] -->
func query[T any](name string, value any, link T) T
Acts upon URL query strings and allows parameters to be added / replaced within them (the parameter being acted upon, name
, will always be removed prior to the new value being added). If value is a slice / array, then an array variable will be created. If value is a map or struct, then a map variable will be created.
Returns a new variable of the original value
data type.
{{ query "test" "value" "/" }}
<!-- /?test=value -->
{{ query "test" "value" "/?test=1" }}
<!-- /?test=value -->
{{ query "test" "value" "/?existing=1" }}
<!-- /?existing=1&test=value -->
<!-- .Slice is: []string{"value1", "value2"} -->
{{ query "test" .Slice "/" }}
<!-- /?test[]=value1&test[]=value2 -->
<!-- .Map is: map[string]string{"name1": "value1", "name2": "value2"} -->
{{ query "test" .Map "/" }}
<!-- /?test[name1]=value1&test[name2]=value2 -->
<!-- .Struct is: struct{ name1, name2 string }{"value1", "value2"} -->
{{ query "test" .Struct "/" }}
<!-- /?test[name1]=value1&test[name2]=value2 -->
func random(...int) int
Generates random numbers.
It can accept various parameter combinations:
<!-- Returns a random number between 0 and 10000 -->
{{ random }}
<!-- Returns a random number between 0 and 100 -->
{{ random 100 }}
<!-- Returns a random number between 200 and 1000 -->
{{ random 200, 1000 }}
<!-- Returns a random number between 200 and 1000 -->
{{ random 1000, 200 }}
<!-- Returns a random number between -50 and 50 -->
{{ random -50, 50 }}
func regexp(find string, value string) [][]string
Finds all instances of find
regexp within value
using regexp.FindAllStringSubmatch
. It only acts on strings, returning an empty string slice for any other values.
{{ regexp "(?:[^ ]*?rk)" "bark clock lark hark block" }}
<!-- [["bark"], ["lark"], ["hark"]]-->
func regexpreplace[T any](find string, replace string, value T) T
Replaces all instances of find
regexp with instances of replace
within value
using regexp.ReplaceAllString
. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ regexpreplace "\n{2,}", "\n", "test\n\n\nstring" }}
<!-- test\nstring -->
{{ regexpreplace "[^ ]in", "replace", "hard to find it in" }}
<!-- hard to replaced it in -->
func render(name string, parameters any) string
Renders a template defined within the current template scope. This differs from the text/template
defined template
keyword in that its scope is more limited (to templates defined within the template itself), but will also accept a variable as the input variable.
This function is mainly used with components when passing wrapped values.
{{ define "template123" }} Template content here {{ end }}
{{ $template := "template123" }}
{{ render $template . }}
<!-- Template content here -->
func replace[T any](find string, replace string, value T) T
Replaces all instances of find
with instances of replace
within value
.
If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ replace "find", "replace", "test find string where find is replaced" }}
<!-- test replace string where replace is replaced -->
func round[T any](precision int, value T) T
Rounds floats to the passed number of decimal places (precision
). If value
is a slice, array or map it will apply this conversion to any float elements that they contain.
Returns a new variable of the original value
data type.
{{ round 3 3.14159 }}
<!-- 3.1416 -->
func rpad[T any](length int, pad string, value T) T
Pads the right of a value
with the pad
string until value
is length
runes long. It will treat HTML entities as a single rune. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ rpad 10 "." "Test" }}
<!-- Test...... -->
{{ "Test" | rpad 9 " ." }}
<!-- Test . . . . -->
func rtrim[T any](remove string, value T) T
Removes the passed characters from the right end of string values. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ rtrim " " "This string. Has TWO sentences. " }}
<!-- This string. Has TWO sentences. -->
{{ rtrim " ." "This string. Has TWO sentences. " }}
<!-- This string. Has TWO sentences -->
{{ rtrim "hT" " This string. Has TWO sentences. " }}
<!-- This string. Has TWO sentences. -->
func sha1(value any) string
The sha1
function creates a SHA1 hash for whatever variable is passed to it. Since hashing algorithms only accept strings, any other type of variable is first given a string value and then hashed.
{{ sha1 "anything" }}
<!-- 8867c88b56e0bfb82cffaf15a66bc8d107d6754a -->
func sha256(value any) string
The sha256
function creates a SHA256 hash for whatever variable is passed to it. Since hashing algorithms only accept strings, any other type of variable is first given a string value and then hashed.
{{ sha256 "anything" }}
<!-- ee0874170b7f6f32b8c2ac9573c428d35b575270a66b757c2c0185d2bd09718d -->
func sha512(value any) string
The sha512
function creates a SHA512 hash for whatever variable is passed to it. Since hashing algorithms only accept strings, any other type of variable is first given a string value and then hashed.
{{ sha512 "anything" }}
<!-- cc27d84e5fdb68439143b6143f80ba4021e4b05380ba412b3652d56ec5ef86824da18eae36caab4a2f2aaddef32dea3058848c75f3415a0ea664d847d8e94b94 -->
func split(separator string, value string) []string
Splits strings on the separator
value and returns a slice of the pieces. It only works on strings and returns an empty slice for all other data types.
{{ split " " "a test string" }}
<!-- ["a", "test", "string"] -->
{{ split "::" "some::joined::data" }}
<!-- ["some", "joined", "data"] -->
func startswith(find string, value string) bool
Tests whether a string value
starts with another string, find
. Returns false if either value is not a string.
{{ if startswith "the" "the quick brown fox" }} starts with the {{ end }}
<!-- starts with the -->
<!-- OR more idiomatically... -->
{{ if "the quick brown fox" | startswith "the" }} starts with the {{ end }}
<!-- starts with the -->
func string(value any) int
Attempts to convert any value
to a string. If conversion is impossible, the nil value ("") will be returned. More complex types are always "".
{{ string "3" }}
<!-- 3 -->
{{ string 3 }}
<!-- 3 -->
func striptags[T any](value T) T
Strips HTML tags from strings. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ striptags "<p>Remove <strong>all</strong> HTML tags</p>" }}
<!-- Remove all HTML tags -->
func substr[T any](offset int, length int, value T) T
Extracts a substring from a value
starting at the specified offset
and including length
runes from that point. If length
is zero, the substring will be taken to the end of the value
. If length
is negative, it is the number of runes from the end of the value
.
If value
is a slice, array or map it will apply this conversion to any valid elements that they contain.
Returns a new variable of the original value
data type.
{{ substr 3 13 "<p>Remove P Tags</p>" }}
<!-- Remove P Tags -->
{{ "<p>Remove P Tags</p>" | substr 3 -4 }}
<!-- Remove P Tags -->
{{ "Do nothing" | substr 3 0 }}
<!-- nothing -->
func subtract[T any](subtract T, from T) T
Subtracts a value from the existing item. If the subtracted value is a simple numeric type this will be treated as a simple maths (recursively on all possible items). If the removed value is a string, it will be cut
from string values (recursively on all possible items). If the removed value is a more complex type (e.g. slice / map), then it is removed on a per key bases as appropriate in a similar manner to Django's subtract function.
<!-- Integers: .Test is 10 -->
{{ subtract 5 .Test }} <!-- 5 -->
{{ subtract -5 .Test }} <!-- 15 -->
{{ subtract 2.5 .Test }} <!-- 8 -->
{{ subtract 2.4 .Test }} <!-- 8 -->
{{ subtract 2.6 .Test }} <!-- 7 -->
{{ subtract "5" .Test }} <!-- 5 -->
{{ subtract "5.5" .Test }} <!-- 5 -->
{{ subtract "string" .Test }} <!-- 10 -->
{{ subtract .Test "string" }} <!-- string -->
<!-- Floats: .Test is 10.0 -->
{{ subtract 5 .Test }} <!-- 5.0 -->
{{ subtract -5 .Test }} <!-- 15.0 -->
{{ subtract 2.5 .Test }} <!-- 7.5 -->
{{ subtract 2.4 .Test }} <!-- 7.6 -->
{{ subtract 2.6 .Test }} <!-- 7.4 -->
{{ subtract "5" .Test }} <!-- 5.0 -->
{{ subtract "5.5" .Test }} <!-- 4.5 -->
{{ subtract "string" .Test }} <!-- 10.0 -->
{{ subtract .Test "string" }} <!-- string -->
<!-- Strings: .Test is "test string" -->
{{ subtract "test" .Test }} <!-- string -->
{{ subtract " string" .Test }} <!-- test -->
<!-- Recursive Slices / Arrays: .Test is [1, 2, 3] -->
{{ subtract 5 .Test }} <!-- [-4, -3, -2] (see Integers for examples) -->
{{ subtract "string" .Test }} <!-- [1, 2, 3] -->
<!-- Recursive Slices / Arrays: .Test is ["string", "test"] -->
{{ subtract "test" .Test }} <!-- ["string", ""] -->
<!-- REMOVE - slices / arrays must be of the same type as added element -->
<!-- Slices / Arrays: .Test is [1, 2, 3], .Remove is [2, 3, 4] -->
{{ subtract .Remove .Test }} <!-- [1] -->
<!-- Slices / Arrays: .Test is ["string value", "slice"], .Remove is ["slice", "string"] -->
{{ subtract .Remove .Test }} <!-- ["string value"] -->
<!-- Recursive Maps: .Test is ["first": 1, "second": 2] -->
{{ subtract 5 .Test }} <!-- ["first": -4, "second": -3] (see Integers for examples) -->
{{ subtract "second" .Test }} <!-- ["first": 1, "second": 2] -->
<!-- Recursive Maps: .Test is ["first": "one", "second": "two"] -->
{{ subtract "two" .Test }} <!-- ["first": "one", "second": ""] -->
<!-- REMOVE - map values must be of the same type as added element -->
<!-- Maps: .Test is ["first": 1, "second": 2], .Remove is ["second": 2, "third": 3] -->
{{ subtract .Remove .Test }} <!-- ["first": 1] -->
func suffix[T any](suffix ...string, value T) T
Suffixes all strings within value
with all strings within suffix
. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ suffix " suffix" "value" }} <!-- value suffix -->
{{ suffix " suffix1" " suffix2" "value" }} <!-- value suffix1 suffix2 -->
<!-- Slices / Arrays: .Test is ["string1", "string2"] -->
{{ suffix " suffix" .Test }}
<!-- ["string1 suffix", "string2 suffix"] -->
<!-- Maps: .Test is [1: "string1", 2: "string2"] -->
{{ suffix " suffix" .Test }}
<!-- [1: "string1 suffix", 2: "string2 suffix"] -->
func time(input ...any) string
Parses dates to return a simple time string (by default: "HH:MM"). Supports Go, Python and PHP formatting standards (for input / output formatting). The last parameter is always the date input.
It can accept various parameter combinations:
<!-- Current date and default output format -->
{{ time }}
<!-- 12:30 -->
<!-- Passed `time.Time` object (default output format) -->
{{ time .Time }}
<!-- 11:30 -->
<!-- Passed Unix time (default output format) -->
{{ datetime 1556015421 }}
<!-- 11:30 -->
<!-- Current time and Go formatting string -->
{{ time "15:04:05" }}
<!-- 12:30:45 -->
<!-- Current time and PHP formatting string -->
{{ time "H:i:s" }}
<!-- 12:30:45 -->
<!-- Passed Go formatting string and `time.Time` object -->
{{ time "15:04:05" .Time }}
<!-- 11:30:12 -->
<!-- Passed Go formatting string and Unix time -->
{{ datetime "15:04:05" 1556015421 }}
<!-- 11:30:12 -->
<!-- Passed Python formatting string and `time.RFC3339` string -->
{{ time "%H:%M:%S" "2020-02-15T11:30:12Z" }}
<!-- 11:30:12 -->
<!-- Passed defined output formatting string (MYSQL), defined input layout (ATOM) and matching date string -->
{{ time "MYSQL", "ATOM" "2020-02-15T11:30:12Z00:00" }}
<!-- 2020-02-15 11:30:12 -->
Date and time functions support various pre-defined formats for simplicity, see date
.
func timesince(t time.Time) map[string]int
Calculates the approximate duration since the time.Time
value. The map of integers contains the keys: years
, weeks
, days
, hours
, minutes
, seconds
.
func timeuntil(t time.Time) map[string]int
Calculates the approximate duration until the time.Time
value. The map of integers contains the keys: years
, weeks
, days
, hours
, minutes
, seconds
.
func title[T any](value T) T
Converts string text to title case. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ title "This string. Has TWO sentences." }}
<!-- This String. Has Two Sentences. -->
func trim[T any](remove string, value T) T
Removes the passed characters from the ends of string values. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ trim " " " This string. Has TWO sentences. " }}
<!-- This string. Has TWO sentences. -->
{{ trim " .hT" "This string. Has TWO sentences. " }}
<!-- is string. Has TWO sentences -->
{{ trim "h." " This string. Has TWO sentences. " }}
<!-- This string. Has TWO sentences. -->
func truncate[T any](length int, value T) T
Truncates strings to a certain number of characters. Is multi-byte safe and HTML aware. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ truncate 5 "hello world"}}
<!-- hello -->
{{ truncate 5 `<a href="#test"><strong>hello world</strong></a>` }}
<!-- <a href="#test"><strong>hello</strong></a> -->
func truncatewords[T any](length int, value T) T
Truncates strings to a certain number of words. Is multi-byte safe and HTML aware. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ truncatewords 3 "hello world how are you?"}}
<!-- hello world how -->
{{ truncatewords 3 `<a href="#test"><strong>hello world</strong></a> how are you?` }}
<!-- <a href="#test"><strong>hello world</strong></a> how -->
func type(value any) string
Returns the value's reflect.Type
as a string. Mainly useful for testing.
{{ type 3.14159 }} <!-- float64 -->
{{ type "test" }} <!-- string -->
<!-- Slice: .Test is []int{1, 2, 3} -->
{{ type .Test }} <!-- []int -->
<!-- Array: .Test is [3]int{1, 2, 3} -->
{{ type .Test }} <!-- [3]int -->
<!-- Map: .Test is map[int]string{2: "second", 1: "first"} -->
{{ type .Test }} <!-- map[int]string -->
func ul(value any) string
Converts slices, arrays or maps into an HTML unordered list.
Other data types will just return a string representation of themselves.
<!-- .Test is slice: [1, 2, 3] -->
{{ ul .Test }}
<!-- produces: -->
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<!-- .Test is map: ["first": "first-content", "second": "second-content"] -->
{{ ul .Test }}
<!-- produces: -->
<ul>
<li>first-content</li>
<li>second-content</li>
</ul>
<!-- .Test is map: ["first": ["slice", "one"], "second": ["slice", "two"]] -->
{{ ul .Test }}
<!-- produces: -->
<ul>
<li>
<ul>
<li>slice</li>
<li>one</li>
</ul>
</li>
<li>
<ul>
<li>slice</li>
<li>two</li>
</ul>
</li>
</ul>
func upper[T any](value T) T
Converts string text to upper case. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ upper "This string. Has TWO sentences." }}
<!-- THIS STRING. HAS TWO SENTENCES. -->
func urlDecode[T any](url T) T
Converts URL character-entity equivalents back into their literal, URL-unsafe forms. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ urldecode "%21 %2A %27 %28 %29 %3B %3A %40 %26 %3D %2B %24 %2C %2F %3F %25 %23 %5B %5D" }}
<!-- ! * ' ( ) ; : @ & = + $ , / ? % # [ ] -->
func urlEncode[T any](url T) T
Converts URL-unsafe characters into character-entity equivalents to allow the string to be used as part of a URL. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ urlencode "! * ' ( ) ; : @ & = + $ , / ? % # [ ]" }}
<!-- %21 %2A %27 %28 %29 %3B %3A %40 %26 %3D %2B %24 %2C %2F %3F %25 %23 %5B %5D -->
(N.B. If OverloadFunctions()
has been used, this function will also replace the built in urlquery
function)
func uuid() string
Generates a unique ID using the github.com/google/uuid
package based on RFC 4122 and DCE 1.1.
{{ uuid }}
<!-- f47ac10b-58cc-0372-8567-0e02b2c3d479 -->
func values(value any) []any
Returns the values of a slice / array / map / struct.
{{ values .Slice }}
<!-- []int{12, 44, 128} -->
{{ values .Map }}
<!-- []string{"value1", "value2", "value3"} -->
func wordcount(value string) int
Counts the number of words (excluding HTML, numbers and special characters) in a string. Only works on strings and returns 0 for any other value.
{{ wordcount "hello world"}}
<!-- 2 -->
{{ wordcount `" <a href="#test"><strong>hello world</strong></a> how 12 " are " you ?` }}
<!-- 5 -->
func wrap[T any](prefix string, suffix string, value T) T
Wraps all strings within value
with a prefix and suffix. If value
is a slice, array or map it will apply this conversion to any string elements that they contain.
Returns a new variable of the original value
data type.
{{ wrap "prefix " " suffix" "value" }} <!-- prefix value suffix -->
<!-- Slices / Arrays: .Test is ["string1", "string2"] -->
{{ wrap "prefix " " suffix" .Test }}
<!-- ["prefix string1 suffix", "prefix string2 suffix"] -->
<!-- Maps: .Test is [1: "string1", 2: "string2"] -->
{{ wrap "prefix " " suffix" .Test }}
<!-- [1: "prefix string1 suffix", 2: "prefix string2 suffix"] -->
func year(times nil|time.Time) int
Returns an integer year from a time.Time
input, or the current year if no time is provided.
<!-- Current date -->
{{ year }}
<!-- 2022 -->
<!-- Passed `time.Time` object -->
{{ year .Time }}
<!-- 2020 -->
func yesno(values ...any) string
Returns "Yes" for true values, "No" for false values and "Maybe" for empty values (maybe
defaults to "No" unless maybe is specifically defined).
Return string options may be customised. If numeric arguments are used, it treats numeric zero as "No", positive numbers as "Yes" and negative numbers as "Maybe" If string, slice, array or map arguments are used, it treats empty as "Maybe", and populated as "Yes".
Examples of use:
<!-- Uses the default "Yes" / "No" returns -->
{{ yesno 1 }}
<!-- Yes -->
{{ yesno 0 }}
<!-- No -->
<!-- Customises the string used for "Yes" -->
{{ yesno "Yep" 1 }}
<!-- Yep -->
{{ yesno "Yep" 0 }}
<!-- No -->
<!-- Customises the strings used for "Yes" and "No" -->
{{ yesno "Yep" "Nope" 1 }}
<!-- Yep -->
{{ yesno "Yep" "Nope" 0 }}
<!-- Nope -->
{{ yesno "Yep" "Nope" -1 }}
<!-- Nope -->
<!-- Customises the strings used for "Yes" and "No" and enables "Maybe" -->
{{ yesno "Yep" "Nope" "Perhaps" 1 }}
<!-- Yep -->
{{ yesno "Yep" "Nope" "Perhaps" 0 }}
<!-- Nope -->
{{ yesno "Yep" "Nope" "Perhaps" -1 }}
<!-- Perhaps -->
<!-- Values do not need to be integers -->
{{ yesno "Yarp" "Narp" "Larp" [1, 2, 3] }}
<!-- Yarp -->
{{ yesno "Yarp" "Narp" "Larp" [] }}
<!-- Larp -->
{{ yesno "Yarp" "Narp" [] }}
<!-- Narp -->