14 KiB
SprigX
1. What is SprigX?
SprigX are extensions to the sprig library (Go docs).
They provide functions that offer more enriched use cases and domain-specific data.
2. How do I Use SprigX?
The same way you would sprig!
package main
import (
htmlTplLib "html/template"
txtTplLib "text/template"
"r00t2.io/goutils/tplx/sprigx"
)
var (
txtTpl *txtTplLib.Template = txtTplLib.
New("").
Funcs(
sprigx.TxtFuncMap(),
)
htmlTpl *htmlTplLib.Template = htmlTplLib.
New("").
Funcs(
sprigx.HtmlFuncMap(),
)
)
They can even be combined/used together.
package main
import (
"text/template"
"github.com/Masterminds/sprig/v3"
"r00t2.io/goutils/tplx/sprigx"
)
var txtTpl *template.Template = template.
New("").
Funcs(
sprigx.TxtFuncMap(),
).
Funcs(
sprig.TxtFuncMap(),
)
// Or:
/*
var txtTpl *template.Template = template.
New("").
Funcs(
sprig.TxtFuncMap(),
).
Funcs(
sprigx.TxtFuncMap(),
)
*/
If a <template>.FuncMap is added via .Funcs() after template parsing, it will override any functions of the same name of a <template>.FuncMap before parsing.
For example, if both sprig and sprigx provide a function foo:
this will use foo from sprigx
package main
import (
"text/template"
"github.com/Masterminds/sprig/v3"
"r00t2.io/goutils/tplx/sprigx"
)
const (
myTpl string = `{{ "This is an example template string." | foo }}`
)
var (
tpl *template.Template = template.Must(
template.
New("").
Funcs(sprig.TxtFuncMap()).
Parse(myTpl),
).
Funcs(sprigx.TxtFuncMap())
)
whereas
this will use foo from sprig
package main
import (
"text/template"
"github.com/Masterminds/sprig/v3"
"r00t2.io/goutils/tplx/sprigx"
)
const (
myTpl string = `{{ "This is an example template string." | foo }}`
)
var (
tpl *template.Template = template.Must(
template.
New("").
Funcs(sprigx.TxtFuncMap()).
Parse(myTpl),
).
Funcs(sprig.TxtFuncMap())
)
and a function can even be
explicitly overridden.
This would override a function foo and foo2 in sprigx from foo and foo2 from sprig, but leave all other sprig functions untouched.
package main
import (
"text/template"
"github.com/Masterminds/sprig/v3"
"r00t2.io/goutils/tplx/sprigx"
)
const (
myTpl string = `{{ "This is an example template string." | foo }}`
)
var (
overrideFuncs template.FuncMap = sprig.TxtFuncMap()
tpl *template.Template = template.Must(
template.
New("").
Funcs(sprigx.TxtFuncMap()).
Parse(myTpl),
).
Funcs(
template.FuncMap(
map[string]any{
"foo": overrideFuncs["foo"],
"foo2": overrideFuncs["foo2"],
},
),
)
)
3. Functions
Expect this list to grow over time, and potentially more frequently than the sprigx functions.
3.1. System/OS/Platform
3.1.1. sysArch
Returns the runtime.GOARCH constant.
3.1.2. sysNumCpu
Returns the value from runtime.NumCPU.
3.1.3. sysOsName
Returns the runtime.GOOS constant.
3.1.4. sysRuntime
This function returns a map[string]string of various information from the runtime stdlib library.
Specifically, the following are returned.
|
Tip
|
The value type is a direct link to the Because all values are mapped as strings, they can be converted back to their native type via e.g. the Sprig conversion functions if necessary. |
| Key | Value Type |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
As a convenience, some of these values also have their own dedicated functions as well:
3.2. Paths
3.2.1. Generic
These operate similar to the path stdlib library and use a fixed / path separator.
3.2.1.1. pathJoin
pathJoin operates exactly like path.Join in stdlib.
|
Warning
|
If you are joining paths in a pipeline, you almost assuredly want |
{{- pathJoin "a" "b" "c" }}
{{- pathJoin "/" "a" "b" "c" }}
{{- pathJoin "/a/b" "c" }}
renders as:
a/b/c
/a/b/c
/a/b/c
3.2.1.2. pathPipeJoin
pathPipeJoin operates like pathJoin with one deviation: the root/base path is expected to be last in the arguments.
This makes it much more suitable for use in template pipelines, as the previous value in a pipeline is passed in as the last element to the next pipe function.
{{- $myBase := "/a" -}}
{{- pathPipeJoin "b" "c" "a" }}
{{- pathPipeJoin "a" "b" "c" "/" }}
{{- $myBase | pathPipeJoin "b" "c" }}
renders as:
a/b/c
/a/b/c
/a/b/c
3.2.1.3. pathSliceJoin
pathSliceJoin joins a slice of path segment strings ([]string) instead of a variadic sequence of strings.
|
Tip
|
The |
{{- $myList := "a,b,c" | splitList "," -}}
{{- $myList | pathSliceJoin }}
{{- ("a,b,c" | splitList ",") | pathSliceJoin }}
{{- ("/,a,b,c" | splitList ",") | pathSliceJoin }}
renders as:
a/b/c
a/b/c
/a/b/c
3.2.1.4. pathSlicePipeJoin
pathSlicePipeJoin operates like pathPipeJoin in that it is suitable for pipeline use in which the root/base path is passed in from the pipeline, but it is like pathSliceJoin in that it then also accepts a slice of path segments ([]string) to append to that base path.
|
Tip
|
The |
{{- $myBase := "/a" -}}
{{- $myList := "b,c,d" | splitList "." -}}
{{- pathSlicePipeJoin $myList $myBase }}
{{- $myBase | pathSlicePipeJoin $myList }}
renders as:
/a/b/c
/a/b/c
3.2.1.5. pathSubJoin
pathSubJoin operates like pathJoin but it expects an explicit root/base path.
The pipeline-friendly equivalent of this is pathPipeJoin.
{{- pathSubJoin "/a/b" "c" }}
{{- pathSubJoin "/" "a" "b" "c" }}
{{- "c" | pathSubJoin "/" "a" "b" }}
renders as:
/a/b/c
/a/b/c
/a/b/c
3.2.2. OS/Platform-Tailored
These operate similar to the path/filepath stdlib library, and use the OS-specific os.PathSeparator.
|
Warning
|
Take special note of the oddness around specifying Windows paths and drive letters in e.g. It is recommended to make use of |
3.2.2.1. osPathJoin
osPathJoin operates exactly like path/filepath.Join in stdlib.
|
Warning
|
If you are joining paths in a pipeline, you almost assuredly want |
{{- osPathJoin "a" "b" "c" }}
{{- osPathJoin "/" "a" "b" "c" }}
{{- osPathJoin "C:\\" "a" "b" "c" }}
{{- osPathJoin "C:" "a" "b" "c" }}
renders as:
| OS | Result |
|---|---|
Windows |
|
Others (e.g. Linux, macOS) |
|
3.2.2.2. osPathPipeJoin
osPathPipeJoin operates like pathPipeJoin (except using OS-specific path separators).
This makes it much more suitable for use in template pipelines, as the previous value in a pipeline is passed in as the last element to the next pipe function.
{{- $myBase := "/a" -}}
{{- osPathPipeJoin "b" "c" "a" }}
{{- osPathPipeJoin "a" "b" "c" "/" }}
{{- $myBase | osPathPipeJoin "b" "c" }}
renders as:
| OS | Result |
|---|---|
Windows |
|
Others (e.g. Linux, macOS) |
|
3.2.2.3. osPathSep
osPathSep returns the os.PathSeparator for this OS.
{{- osPathSep }}
renders as:
| OS | Result |
|---|---|
Windows |
|
Others (e.g. Linux, macOS) |
|
3.2.2.4. osPathSliceJoin
osPathSliceJoin operates like pathSliceJoin but with OS-specific path separators.
|
Tip
|
The |
{{- $myList := "a,b,c" | splitList "," -}}
{{- $myList | osPathSliceJoin }}
{{- ("a,b,c" | splitList ",") | osPathSliceJoin }}
{{- ("/,a,b,c" | splitList ",") | osPathSliceJoin }}
renders as:
| OS | Result |
|---|---|
Windows |
|
Others (e.g. Linux, macOS) |
|
3.2.2.5. osPathSlicePipeJoin
osPathSlicePipeJoin operates like pathSlicePipeJoin but with OS-specific separators.
|
Tip
|
The |
{{- $myBase := "/a" -}}
{{- $myList := "b,c,d" | splitList "." -}}
{{- osPathSlicePipeJoin $myList $myBase }}
{{- $myBase | osPathSlicePipeJoin $myList }}
renders as:
| OS | Result |
|---|---|
Windows |
|
Others (e.g. Linux, macOS) |
|
3.2.2.6. osPathSubJoin
osPathSubJoin operates like pathSubJoin but with OS-specific separators.
The pipeline-friendly equivalent of this is osPathPipeJoin.
{{- osPathSubJoin "/a/b" "c" }}
{{- osPathSubJoin "/" "a" "b" "c" }}
{{- "c" | osPathSubJoin "/" "a" "b" }}
renders as:
| OS | Result |
|---|---|
Windows |
|
Others (e.g. Linux, macOS) |
|
3.3. Strings
3.3.1. extIndent
extIndent allows for a MUCH more flexible indenter than the sprig indent function.
It works with both Windows (\r\n) and POSIX (\n) linebreaks.
|
Tip
|
If |
It has quite a few arguments, however:
{{ extIndent <levels> <skipFirst> <skipEmpty> <skipWhitespace> <indentString> <input> }}
Where:
-
<levels>: The level of indentation for the text. If less than or equal to0,extIndentjust returns<input>as-is and NO-OPs otherwise. -
<skipFirst>: If true, skip indenting the first line. This is particularly handy if you like to visually align your function calls in your templates. -
<skipEmpty>: If true, do not add an indent to empty lines (where an "empty line" means "only has a linebreak"). -
<skipWhitespace>: If true, do not add an indent to lines that only consist of whitespace (spaces, tabs, etc.) and a linebreak. -
<indentString>: The string to use as the "indent character". This can be any string, such as" ","\t",".","|","=="etc. -
<input>: The text to be indented. Because it is the last argument,extIndentworks with pipelined text as well.
3.4. Debugging
3.4.1. dump
The dump function calls the Sdump function from go-spew (github.com/davecgh/go-spew/spew) for whatever object(s) is/are passed to it.
sprigx does not allow setting GOMAXPROCS, this value only contains the current GOMAXPROCS value.