Currently Selmer HTML-escapes all values by default, with |safe and a dynamic variable to opt out. It would be useful to configure the default escape function per render call, to support other output contexts like JSON or URLs.
Proposed API
(binding [selmer.util/*escape-fn* my-escape-fn]
(selmer/render template ctx))
This allows correct escaping for the relevant context while keeping existing ways to opt out. Maybe the new idiomatic way to opt out of escaping would be to rebind it to identity.
Motivation
We're considering Selmer for a use case where we want to template HTTP requests. So with this feature we could do something like this.
URL template:
/endpoint?param1={{some.field}}¶m2={{some_other_field}}
(binding [selmer.util/*escape-fn* url-encode]
(selmer/render template ctx))
;; => /endpoint?param1=my%20value¶m2=12345
JSON body template:
{"param1":{{some.field}},"param2":{{some_other_field}}}
(binding [selmer.util/*escape-fn* write-json-string]
(selmer/render template ctx))
;; => {"param1":"my\nvalue","param2":{"some_other": "json_value"}}
Form body template is also a use case we want but it's just the same as URL in terms of escaping.
Implementation
Should be simple enough - initialize the *escape-fn* variable bound to escape-html function defined in the code, and then call this variable instead when escaping.
I'd just want to make sure - would chained filters be impacted by a custom escaping function? For example value|hash:"md5"|lower with a string-to-json escaping, would the function be applied several times, once between each step? If so then this approach might not be suitable for us :(
After inspecting the code looks like escaping happens once at the end of the chain which is perfect.
Currently Selmer HTML-escapes all values by default, with
|safeand a dynamic variable to opt out. It would be useful to configure the default escape function per render call, to support other output contexts like JSON or URLs.Proposed API
This allows correct escaping for the relevant context while keeping existing ways to opt out. Maybe the new idiomatic way to opt out of escaping would be to rebind it to
identity.Motivation
We're considering Selmer for a use case where we want to template HTTP requests. So with this feature we could do something like this.
URL template:
JSON body template:
Form body template is also a use case we want but it's just the same as URL in terms of escaping.
Implementation
Should be simple enough - initialize the
*escape-fn*variable bound toescape-htmlfunction defined in the code, and then call this variable instead when escaping.I'd just want to make sure - would chained filters be impacted by a custom escaping function? For examplevalue|hash:"md5"|lowerwith astring-to-jsonescaping, would the function be applied several times, once between each step? If so then this approach might not be suitable for us :(After inspecting the code looks like escaping happens once at the end of the chain which is perfect.