tera
tera copied to clipboard
Please add regex-aware replace filter.
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
What would it look it? Any example in Jinja2/Django?
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... :)
That's the main issue, if you start adding some regex support it is going to be hairy very fast :)
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.
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.
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...
@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...
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)
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!
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.
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 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.
@Keats I'm not a git-cliff maintainer, I'm just another user.
I am in the same case as @sirthias.
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 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".
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
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