Skip to content

Configurable default escape function #337

Description

@SuperCuber

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}}&param2={{some_other_field}}
(binding [selmer.util/*escape-fn* url-encode]
  (selmer/render template ctx))
;; => /endpoint?param1=my%20value&param2=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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions