Regex with jinja? - regex

I would like to use regexes in Jinja as:
{{ foo | regex_replace('[^a-z0-9]', '_') }}
I've read that ansible provides additional filters such as regex_replace.
Would it be the best solution to define a custom filter in this particular case?

Related

Why django is not accepting spaces in template?

{% %} means that this is a django template delimiter. So inside {% %} the space should not matter I guess.
Now in the example:
{{ post.title }}
This is showing expected output whereas
{{ post.title }}
is showing error.
Why this is sensitive to whitespace?
Django template tags allow you to have positional and named parameters, so, if you have a space, it will assume that pk Is the first argument, = the seccond and so on.
So, if you you are passing named parameters, you have to use = without spaces, and if you are using positional parameters, you don't use = and separate them just by a space.
Because django templates are text processed and this is the syntax, you could try the same thing in bash, this is off-topic, but it is processed the same way that statements are sensitive to whitespace.
valid in bash
declare TEST=SOMETHING # is valid
invalid in bash
declare TEST = SOMETHING # is invalid
(same as in django template language)
If your question was Why this is sensitive to whitespace? than the answer is Because of syntax. Some languages are case sensitive some are case insensitive, in some you must prefix every variable with dollar ($). Thats only the syntax matter. Everything is processed and if you want your pc to understand what is happening, than it must be formally expressed with correct syntax.
There are Django docs: https://docs.djangoproject.com/en/2.0/topics/templates/#syntax

Regex, I just don't get it right

I just don't get my Regex right:
I have the following template:
<!-- Defines the template for the tabs. -->
{{TMPL:Import=../../../../Data/Templates/Ribbon/tabs.tmpl; Name=Tabs}}
<div class="tabs">
<ul role="tablist">
{{BOS:Sequence}}
<li role="tab" class="{{TabType}}" id="{{tabId}}">
<span>{{TabFile}}</span>
</li>
{{EOS:Sequence}}
</ul>
</div>
{{Render:Tabs}}
I would like to find everything between {{}} except the tags that begins with {{BOS, {{EOS, {{TMPL, {{Render
Here are a couple approaches:
Attempt 1:
({{).*(}})
This selects everything between {{ }} tags, which is not good.
Attempt 2:
({{)[^TMPL][^BOS][^EOS][^Render].*(}})
This will make that {{TabType}} and {{TabFile}} are not selected anymore and I just don't know why.
With some other regex, I get that {{TabType}}" id="{{tabId}} is selected as one match.
Does anyone have a clue on how to solve this, I really need a regex Guru :-)
You can use negative lookahead based regex like this:
{{(?!TMPL|[BE]OS|Render).*?}}
RegEx Demo
You have to use the following regex to get the content between braces:
\{\{(.*?)\}\}
Working Demo
If you want to exclude the content from the comment you posted you can use a regex technique to exclude what you don't want and keep what you want at the end of the regex:
\{\{BOS:Sequence\}\}|\{\{EOS:Sequence\}\}|\{\{TMPL:Import.*?\}\}|\{\{Render:Tabs\}\}|\{\{(.*?)\}\}
Working demo
By the way, if you want to have a shortcut for above regex you can use:
\{\{(?:BOS|EOS):Sequence\}\}|\{\{TMPL:Import.*?\}\}|\{\{Render:Tabs\}\}|\{\{(.*?)\}\}
This is a very useful technique for pattern exclusion that I glad to learn it from Anubhava and zx81 (they rock using regex pattern). For this regex technique you can find the content you need using capturing groups (check the green highlights on the screenshot below):
Using [^TMPL] and the like won't work because these are character classes. You could use a negative lookahead, though (or even lookbehind depending upon the regex library you are using).
\{\{(?!BOS:)(?!EOS:)(?!Render:)(?!TMPL:)(.*?)\}\}
Still I get the feeling that you want the BOS, EOS, etc. to just be strings in the template with {{ and other values to be interpolated. If you are using handlebars or something, you can have strings interpolated:
{{'{{BOS:Sequence}}'}}

regex issue for interpolate setting in underscore.js

I have following regex and template for underscore.js templates.
the problem is that the regex for interpolate is not working properly, what will be correct regex?
Regex
var settings = {
evaluate: /\{\{\#([\s\S]+?)\}\}/g,
interpolate: /\{\{[a-zA-Z](.+?)\}\}/g
};
Template
{{# if ( item ) { }}
{{ item.title }}
{{# } }}
The template compiler will use the last capture group in the expressions to build the JavaScript form of the template. In your case, the interpolate will (as noted by Jerry) ignore the first alphabetic character so {{ab}} will end up looking for b in the template parameters. Your regex also doesn't account for leading whitespace. You'd want something more like this:
/\{\{\s*([a-zA-Z](?:.+?))\s*\}\}/g
or better, just leave out the original group instead of converting it to a non-capturing group:
/\{\{\s*([a-zA-Z].+?)\s*\}\}/g
Or even better, get right to the heart of the problem and say exactly what you mean:
/\{\{([^#].*?)\}\}/g
I think the problem that led you to your original regex is that interpolate is checked before evaluate; that order makes sense when interpolate is looking for <%= ... %> and evaluate is looking for <% ... %> (i.e. the default delimiters are being used). In your case, you need a bit of extra [^#] trickery to get around the regex checking order.
Similarly, we can simplify your evaluate regex:
/\{\{#(.+?)\}\}/g
Demo: http://jsfiddle.net/ambiguous/V6rv2/
I'd also recommend that you add an escape pattern for completeness.

Using regular expression in Django templates

I wonder if it is possible using regular expression in Django templates:
{{form.deal_template_name.value}}
I would like to replace both spaces and dot's with _. (Otherwise the link would have trouble with the target)
{{form.deal_template_name.value}}
.replace(/ /g,"_").replace(/\./g,"_")
How to do that though in template directly, is that possible?
If you really want to shoot yourself in the foot:
Custom django filter that does that:
{% load replace %} {{ mystring|replace:"/l(u+)pin/m\1gen" }}

How do I prevent Django from interpreting a block which contains curly quotes?

I'm working on a website which uses Django templates, and I have to produce HTML which contains paired curly quotes. Is there any way to disable Django's tag processing for a block of code? Something like a literal block tag would be nice, so that:
{% literal %}
{% LITERAL {{ BRACES }}
{% endliteral %}
... would produce {% LITERAL {{ BRACES }} in the output.
For the record, this is possible now with the template tag verbatim.
EDIT:
Your syntax is currently impossible with the current lexer / parser system.
Why? Basically the template system has a Lexer and a Parser. The Lexer takes the template string as input, and tokenizes it. The parser then takes the list of tokens in its constructor and parses them into a list of a bunch of Nodes for the compiled template. The template tags and filters only have access to the already constructed parser -- you can't access the initial lexer string. See the comments in django/templates/__init__.py
However, there is a solution. It's not mine (see below), but its to basically use server side includes {% ssi some_file.html %} to include an extra file that has the literal text. Yes this is an ugly solution; but without a major rewrite of the templating system it will have to suffice.
Easy Way to Escape Django Template Variables
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#templatetag