Krikri::VariableSubstitutor
The ONE shared "recursive re-templating" helper: re-renders value when its raw form is still a String containing Jinja markers. This used to exist as four independently-maintained copies (FilterEngine's, ComparisonEvaluator's, ConditionalEvaluator's class methods, and VariableLookup's - the last deliberately NOT folded in here, see below). Every one of the folded-in copies had the same multi-span bug ("{{ a }}-{{ b }}" mangled by naive 2-char slicing) and the same "{%"/"{#" block-tag gap fixed independently, and each fix had to be re-applied to the others by hand - the comment trails in the originals documented that treadmill explicitly.
Algorithm (identical to what the three folded copies did):
- nil/untouched values pass through unchanged (also when vars is nil - FilterEngine's optional-context case).
{%/{#block tags or comments go through the FULL Crinja renderer (ExpressionEvaluator has no concept of block tags).- exactly one
{{ }}span spanning the WHOLE string goes through ExpressionEvaluator directly - the only path that preserves a non-string result type. - anything else (multiple spans, literal text around a span) goes through VarSubstitutor#substitute.
VariableLookup keeps its own copy ON PURPOSE: it routes the mixed/ multi-span case through CrinjaRenderer instead of VarSubstitutor, a deliberate behavioral difference fixed after real-host bugs - see its own comments before even thinking about unifying that one too.
Class methods
The ONE shared dotted-path walker for plain hash navigation
(result.rc, ansible_facts.os_family) - resolves parts (the
split of a dotted expression) against base by successive Hash
lookups, nil on the first miss or on a non-Hash hop. Used to exist
as three divergent copies (VariableLookup, ComparisonEvaluator,
ArraySlicer); VariableLookup keeps its own richer walker ON
PURPOSE (it also handles list indexing, numeric dot-indexing and
method calls - see its own comments), but the two simple
consumers now share this one so a fix lands once for both.
Nested types
- Krikri::VariableSubstitutor::ArraySlicer
- Krikri::VariableSubstitutor::ComparisonEvaluator
- Krikri::VariableSubstitutor::CrinjaRenderer
- Krikri::VariableSubstitutor::ExpressionEvaluator
- Krikri::VariableSubstitutor::FilterCore
- Krikri::VariableSubstitutor::FilterEngine
- Krikri::VariableSubstitutor::LazyCrinjaContext
- Krikri::VariableSubstitutor::Rerender
- Krikri::VariableSubstitutor::TemplateRecursionError
- Krikri::VariableSubstitutor::TemplateSyntaxError
- Krikri::VariableSubstitutor::Undefined
- Krikri::VariableSubstitutor::UnknownTestError
- Krikri::VariableSubstitutor::VariableLookup