AshDispatch.SafeRender (AshDispatch v0.5.1)
View SourceHTML-safe rendering helpers for AshDispatch.TemplateResolver.
When TemplateResolver renders an email.html.heex template it
preprocesses HEEx-style {@var} markers into <%= @var %> and evaluates
the result via EEx.eval_string/2. Plain EEx does not HTML-escape
interpolated values, so any user-controlled string flowing through
prepare_template_assigns/2 (lead name, contract recipient, customer
comment, etc.) would land raw in the rendered email — a real injection
vector.
The preprocessor wraps every auto-converted {@var} expansion in
AshDispatch.SafeRender.escape/1 for HTML formats so escaping is the
default, matching Phoenix HEEx semantics.
Opt-out (when you genuinely have safe markup)
<p>{AshDispatch.SafeRender.raw @already_safe_html}</p>raw/1 returns its argument unchanged and is recognized as a "not a
bare @var" expression by the preprocessor, so it's emitted as plain
<%= raw(@x) %> without the escape wrapper.
Phoenix.HTML interop
If an assign value is a {:safe, iodata} tuple (Phoenix's Phoenix.HTML.Safe
output) escape/1 returns the iodata as-is — the value already
promises it is escaped.
Summary
Functions
Escape a value for safe inclusion in HTML output.
Mark a value as already-safe HTML so the preprocessor's auto-escape is bypassed.
Functions
Escape a value for safe inclusion in HTML output.
nil→""(so{@missing_field}doesn't render the string "nil")binary→ HTML-escapedinteger/float/atom→ string-converted (no escape needed — these can't contain markup characters that change meaning){:safe, iodata}→ returned unchanged (already escaped by caller)- Anything else →
to_string/1then escape
@spec raw(value) :: value when value: any()
Mark a value as already-safe HTML so the preprocessor's auto-escape is bypassed.
In templates:
<p>{AshDispatch.SafeRender.raw @trusted_html}</p>Returns its argument unchanged — the wrapper is only meaningful as a
signal to the HEEx preprocessor, which sees raw(@x) is not a bare
@var and emits <%= raw(@x) %> without escape.