Functions
Template functions enable you to build dynamic templates in a way that's intuitive and composable. Slumber templates behave as a simple functional language: functions take arguments and evaluate to values. All functions are provided by Slumber; there is no way to define your own functions.
For the list of available functions, see Template Functions.
Arguments
Slumber functions take two types of arguments:
- Positional arguments are specified in a specific and are always required
- Keyword arguments as passed in the form
key=value
, can be specified in any order (provided all positional arguments are passed first), and are always optional
In the function signatures listed below, keyword arguments are specified with a ?
while positional arguments are not.
For example, this function takes 2 required positional arguments and 2 optional keyword arguments:
func(a: string, b: boolean, c?: string, d?: bytes): string
Given this function signature, the following are all valid calls:
func("hello", true);
func("hello", true, "world");
func("hello", true, c="world");
func("hello", true, d=b"bytes");
func("hello", true, c="world", d=b"bytes");
func("hello", true, d=b"bytes", c="world"); # Keyword args can be reordered
The follow calls are not valid:
# WARNING: Invalid code!!
func("hello") # Required arguments omitted
func(c="world", "hello", true) # Keyword argument before positional
func("hello", true, c="world", c="world") # Keyword argument given twice
func("hello", true, "world") # Optional arguments must be given by name
Defaults
If a keyword argument is omitted, it will be replaced by a default value. In most cases, the default will be based on the type of the argument:
boolean
:false
float
:0.0
integer
:0
string
:""
bytes
:b""
array
:[]
value
:null
If the default varies from this list, it will be specified in the Parameters
section of the function's docs.
Pipe Operator
It's common to take the output of one function and pass it to another. This is especially useful for filter-esque functions like jsonpath
and trim
that modify incoming input. Here's an example using command
and trim
# Command output often includes a trailing newline that we want to trim away
trim(command(["echo", "hello"]))
This works, but it's a bit backward: we run the command
, then trim
it. To make these types of composed operations easier to read and write, Slumber supports the pipe operator |
. The left-hand side of the operator can be any expression, but is typically a function call. The right-hand side must be a function call. The left-hand side is evaluated, then the result is passed as the last argument to the right-hand side. We can rewrite the same expression from above with the pipe:
# Equivalent to the above expression
command(["echo", "hello"]) | trim()
This is equivalent, but easier to read because the lexical ordering of calls matches the evaluation order.
Unlike other template languages such as Jinja and Tera, the right-hand side of a pipe must include parentheses, even if they argument list is empty. Additionally, other languages have a distinction between "functions" and "filters", and only filters can be used on the right-hand side of a pipe operation. This distinction does not exist in Slumber; any function can be used on the right-hand side of a pipe, as long as it takes at least one positional argument.
Remember: the piped value is passed as the last positional argument to the right-hand side. That means it will be inserted after other positional arguments but before any keyword arguments. Here's another example, using response
and jsonpath
.
response('login') | jsonpath("$.token", mode="single")
# is equivalent to
jsonpath("$.token", response('login'), mode="single")