tera icon indicating copy to clipboard operation
tera copied to clipboard

Please add regex-aware replace filter.

Open yacoob opened this issue 6 years ago • 18 comments
trafficstars

I wanted to get the site name (as in, no protocol prefix) from config.base_url. It'd be nice to use replace filter for this. Right now I have config.base_url|split(pat='/')|last. :D

yacoob avatar Jun 25 '19 23:06 yacoob

What would it look it? Any example in Jinja2/Django?

Keats avatar Jul 05 '19 22:07 Keats

I don't think I've seen one in Jinja2. It'd be something along the lines of:

regex_replace(s, pattern, replacement)

with pattern being a possibly anchored regexp string and replacement just a text.

On second thought, the obvious next step is to support matched groups substitution in replacement and that might make things bit hairy... :)

yacoob avatar Jul 05 '19 22:07 yacoob

That's the main issue, if you start adding some regex support it is going to be hairy very fast :)

Keats avatar Jul 06 '19 09:07 Keats

The thing I'd like particularly from this feature is to be able to replace multiple things at once. In particular if you wanted to get rid of all lowercase letters at once you'd need 26 replaces currently, for instance. I have to get rid of fewer things for my use but it would still be useful to have a regex replace.

lf- avatar Mar 09 '21 09:03 lf-

After some more Zola hacking tonight, I have another use case where I believe I need this: I want to replace \n\n with \n and \n with a space, in order to enable hard wrapping in my source for image descriptions (which are not HTML so I can't send them through markdown; markdown(inline=true) will put superfluous entities in). It seems that Tera/Zola don't parse \r or \n in string literals in templates. It's true that this could be done with three replaces if these literals were supported ("\n\n" -> "\0", "\n"->"", "\0" -> "\n" for example), but a regex is a more clear way of writing it.

lf- avatar Mar 09 '21 10:03 lf-

That's the main issue, if you start adding some regex support it is going to be hairy very fast :)

What's hairy about it? Is it hard to implement? Does it go against some underlying guiding principle wrt Tera?

Regex search+replace appears to me like quite a "standard" feature that should neither be hard to implement nor use. But maybe I'm missing something...

sirthias avatar Mar 24 '22 15:03 sirthias

@Keats ping!

Can you answer to @sirthias? Since my questions/concerns are the same.

It's been a year since that message with no answer...

bdovaz avatar Apr 13 '23 18:04 bdovaz

It expands to many ways to use it, from a basic search/replace, you can have named groups replace, regex sets, get all matches and it's going to compile the regex on every render which isn't ideal. Depending on the usecase, it's better to write your own filter function (although there are some issues with \n etc in Zola that need to be fixed in Tera)

Keats avatar Apr 14 '23 10:04 Keats

Hmm... I don't quite follow you here. There is no requirement to support every and all regex features. It's fine to start with some basic feature set and, for example, not support named groups or even any capture groups, if that's somehow too "hairy".

Compiling the regex on every render also hardly seems like a real problem. How many micro-seconds is that going to take? And if there really is some performance drawback then it should be fine to surface the issue in the documentation and let me as the user decide on whether I'd like to take the perf hit or not! Currently it feels like tera is trying to make that decision for me, which feels a bit overreaching.

Depending on the usecase, it's better to write your own filter function ...

I'd go out on a limb here and say that, in 99.5% of all cases, writing my own filter function will not be the better tradeoff wrt to my dev and maintenance time. If I need a replace logic that can easily expressed with a simple regex I don't want to write a custom function!

sirthias avatar Apr 14 '23 20:04 sirthias

In addition to what @sirthias says, in our case we use Tera through https://git-cliff.org/docs/templating/syntax so in our case the rendering is 1 time. With this I want to say that like any tool, you have to know how to use it, not because it can do something you should abuse it. But at the same time, you should not eliminate the possibility that we can use it because of the misuse that some may give it.

bdovaz avatar Apr 16 '23 12:04 bdovaz

But at the same time, you should not eliminate the possibility that we can use it because of the misuse that some may give it.

It's not eliminated, adding a custom filter/function is trivial, here's the replace for example: https://github.com/Keats/tera/blob/master/src/builtins/filters/string.rs#L186-L201 (I see you have added one already in git-cliff so you're aware of it) and here's a PR to add a function like that in Zola: https://github.com/getzola/zola/pull/2163.

I just don't see why this would be need to be built-in.

Keats avatar Apr 17 '23 15:04 Keats

@Keats I'm using tera indirectly through zola and as such don't have the ability to implement a custom function. This would be one example of a drawback of custom functions over built-in functionality: Anyone, who is not using tera as a direct dependency of their own code but rather indirectly as the end-user of some other tool has to work only with what teras built-in functionality offers.

sirthias avatar Apr 17 '23 15:04 sirthias

@Keats I'm not a git-cliff maintainer, I'm just another user.

I am in the same case as @sirthias.

bdovaz avatar Apr 17 '23 16:04 bdovaz

Sure I understand but we cannot add every features under the sun in Tera just because some some other tools might not implement them

Keats avatar Apr 19 '23 15:04 Keats

@Keats Yes, I completely agree. However, this ticket is not for "all features under the sun", but a simple regex-aware search & replace filter, as many other tools offer it.

I can see that you are somehow opposed to adding such a feature, which is fine (even though you haven't so far revealed the real reason). This is open-source, tera is your baby and you are not in any way obliged to do anything. I'd therefore suggest you close this ticket as "won't fix".

sirthias avatar Apr 19 '23 15:04 sirthias

even though you haven't so far revealed the real reason

There isn't a hidden reason. jinja2 doesn't have a regex search and replace either, ansible added a regex_replace filter because it was an obvious need for them. Django templates doesn't support it either I think? We could add tons of "simple" things (base64, i18n, unicode stuff, markdown, md5, sha, etc) but I don't really see how that's better than downstream implementing what they need, not to mention the different versions of the deps might results in tools getting the dependency several times if they use it as well and have different MSRV policies.

I'll leave the issue open for now so I don't forget about it

Keats avatar Apr 19 '23 16:04 Keats

jinja2 doesn't have a regex

It's true, I remember I had to create a custom python extension to add regex support to mkdocs, due to the lack of support in jinja2:

import re
from jinja2 import evalcontextfilter

@evalcontextfilter

# regex replacer
# https://stackoverflow.com/a/12825283/13448666
# https://github.com/pallets/jinja/issues/1801
def regex_replace(eval_ctx, s, find, replace):
    return re.sub(find, replace, str(s))

I would love to have something similar built-in in tera

AlphaJack avatar Jan 22 '24 18:01 AlphaJack