Shaping Data with Filters and Tests
Scenario: A cipher list was pasted from a chat message as one long string. The template calls | join(':') on it and produces a string with a colon between every single character.
New words, in plain English
- Filter - a transformation applied with a pipe:
{{ value | filter }}. - Test - a boolean check used with
is:{{ path is defined }}. join- turns a LIST into a string with a separator between elements.select/map- filter a list, or extract one attribute from every element.combine- merges two dictionaries.
Filters transform values inside {{ }}, and knowing a handful well removes most of the awkward YAML people write to avoid them.
The scenario is a type error, and it is common. join operates on a list. Applied to a string, a string is a sequence of characters, so it happily joins the characters. The fix is not a cleverer filter - it is making the data a real YAML list:
tls_ciphers:
- HIGH
- '!aNULL'
- '!MD5'
The filters worth knowing on day one: default(x) for fallbacks; join(sep) for list-to-string; length; upper/lower; basename/dirname for paths; int/bool/string for type coercion; to_json/from_json; map('attribute', 'name') to pull one field from every element; select/reject to filter a list; unique; sort; and combine to merge dictionaries.
Tests are used with is: is defined, is undefined, is none, is match('regex'), is version('2.0', '>='). when: app_version is match('^\\d+\\.\\d+\\.\\d+