sindresorhus / pupa

Simple micro templating
MIT License
361 stars 22 forks source link

Support filters #29

Open tommy-mitchell opened 1 year ago

tommy-mitchell commented 1 year ago

Many templating languages support filtering individual interpolated values:

"Hello, {name | capitalize}!"
//=> with {name: "john doe"} => "Hello, John Doe!"

pupa supports transforming all values, but not individual ones. The regex to match items could be modified to:

/{(\d+|[a-z$_][\w\-$]*?(?:\.[\w\-$]*?)*?)(?: \| [^ }]+)*}/gi

This would match an arbitrary number of filters separated by |. (regex101)

Filters would just be an object of functions passed to pupa and would be applied in order from left to right. Filters in the template without a match could have the same semantics as a missing value (either get ignored or throw, perhaps with a new MissingFilterError).


Related, some further improvements to the regex could be supporting arbitrary whitespace and characters:

/{\s*([^\s}|]+)\s*(?:\|\s*[^}]+\s*)*}/gi
sindresorhus commented 1 year ago

Related, some further improvements to the regex could be supporting arbitrary whitespace and characters:

The regex is intentionally strict, from what I can remember: https://github.com/sindresorhus/pupa/commit/9210fdfbc7a48c652c67d215823c0279f9102315

sindresorhus commented 1 year ago

I kinda like it, but I'm also concerned about:

tommy-mitchell commented 1 year ago

That's fair. I've been working on a similar library to extend pupa with filters and conditional rendering, the latter of which requires a parser, but my first attempt used the second regex and I was thinking of using pupa until I finished the parser.

I hadn't fully thought of the vulnerabilities. If I do end up finishing the parser, I'd be happy to trim it down for this library.