Referrering to jinja2 variables inside of a string - jinja2

I am using the jinja2 templating language to create dual language documents. To that end, I have created a macro called select_lang which takes two strings as an argument, the text in the primary language and in the secondary language, and returns it on the format
<text in primary language> / <i><text in secondary language></i>
Sometimes, as input, I want do use a jinja2 variable, and this is where I struggle. Given the following code:
<!DOCTYPE HTML>
{% set bilingual = primary_lang and secondary_lang %}
{% from 'templates/partials/macro_select_lang.j2.html' import select_lang with context %}
<html>
<body>
{{ select_lang('Testo in italiano','Text in English') }}<br>
{{name.upper()}}<br>
{{ select_lang('Ciao, {{name.upper()}}','Hello, {{name.upper()}}') }}
</body>
</html>
I get this output:
Testo in italiano / *Text in English*
JANE DOE
Ciao, {{name.upper()}} / Hello, {{name.upper()}}
but the desired outcome would be that {{name.upper()}} was evaluated before being passed on to the select_lang macro.
I have searched the jinja2 documentation, but I can't find any relevant topic.
Note: one might think that this is a silly macro which could be replaced with some simple html-code. This is true in this example, but in the real application it does a whole lot more, so replacing the macro does not solve the problem; I need to evaluate the expression before passing it on.
In a regular programming language, I would have written something like
{{ select_lang('Ciao, ' + {{name.upper()}},'Hello, ' + {{name.upper()}}) }}
but this does not work and I suppose jinja2 does not offer an operator for string concatenation.

It seems you have too many curly braces!
Try:
{{ select_lang('Ciao, ' + name.upper(),'Hello, ' + name.upper()) }}
As you are already inside a {{...}} statement...

Related

Create an IF statement for a Variable to see if it contains a range of letters

{% if val|first in 'ABCDEFG' %}
This works but doing it this way seems a little clumsy to me. Especially with the number of if statements I will be creating.
I've been searching for a solution for hours but can't quite find what I need. I imagine there is an option to help clean up my script.
Is there a way to make this something like: { if val|first in 'A-G' %} ? Bonus points if you can help me make it case insensitive.
I hope this is the answer you are looking for.
{% if val|first|lower in 'a'-'g' %}
This will convert the first character of val to uppercase and check if it is within the range of A-G. You can make it case insensitive by converting it to either upper or lower.

Type Conversion in Jinja 2

I am trying to convert the string value in 'snrMinMarginUp' to integer or float in Jinja 2. I tried to lookup every possible solution, but got no luck. Any help would be highly appreciated!
{% if 'properties' in value %}
{{ value['serviceProfile']['snrMinMarginUp'] }}
{% endif %}
You can use the float or int filters to coerce a value to a float or int, as in:
{{ value.serviceProfile.snrMinMarginUp|float }}
The example you've given in your question is a little ambiguous -- because you're just displaying the value, it doesn't really matter whether the value is numeric or a string. If this solution doesn't work out for you, please update your question to show a complete example of where things aren't working for you.

Render specific item from array using *ngFor index in Angular 8

I am rendering a list using *ngFor. I only want the next item to be rendered using index. I have tried a number of things but can't get it to work:
Next: {{ exhibit{{ i + 1 }}.fields.artist }}
Next: {{ exhibit[i + 1].fields.artist }}
What am I doing wrong?
Not sure why you do you want to render a list like this, but you can accomplish this using ngFor as below. You need to write the entire template expression inside double curly braces instead of just index.
Next: {{ exhibit[i + 1].fields.artist }}
Please find proof of concept here: https://stackblitz.com/edit/angular-cwxgee

Break up Long title attribute Value

I have an web page which has tooltip set as follows:
title="Tel: {%- recordFields.providerTel || 'N/A' %} Email: {%-recordFields.providerEmail || 'N/A' %}"
The line occupies 142 columns...
Is there a way to break up the title string in the source so that it can span multiple lines?
Something along these lines:
title="Tel: {%- recordFields.providerTel || 'N/A' %} \
Email: {%-recordFields.providerEmail || 'N/A' %}"
In a comment on the question I asked:
You only want it to span multiple lines in the source, right? The actual value shouldn't have newlines (e.g., when used)?
and you said:
Let's say that. In this particular case, I also want a newline in the output, but I'll remove it for clarity.
It's a really fundamental part of the question. :-)
If you do want the newlines, the answer is easy but (to my mind) unsatisfying: Just put them in, literally:
<div title="Tel: {%- recordFields.providerTel || 'N/A' %}
Email: {%-recordFields.providerEmail || 'N/A' %}">...</div>
Live example. Note that it's important not to have leading whitespace on the next line, because that whitespace is part of the attribute value. This is what makes it unsatisfying to me, because having that subsequent line start at column 0 in something that's otherwise indented seems unclean (and some tools will fight with you, trying to indent it).
If you don't want the newlines in the attribute's value, I'm not aware of a way to do it. According to the HTML specification, an attribute's value is "...Attribute values are a mixture of text and character references...", and if we follow that link for "text" it doesn't say anything about putting source-only linebreaks in the value.
Since you seem to be using some kind of templating engine, if it runs server-side then you could of course define a property on the values object to hold the title string:
title="{%- getTitleFor(recordFields) %}"
...but that moves the content out of your HTML source (where content generally belongs) into your server-side language source, so it's not a great alternative.

Newlines not being interpreted when getting from sqlite db?

I'm using Flask and Sqlite.
I take some string, which contains newlines, and store it in the db. At some later point I get it from the db and include it on some page, and the string shows up without newlines. What's with that?
For example if I have
{{ entry.content }}
in my template, and the entry that was stored had content "hello\nhello", it displays "hellohello" on the page.
However if I have
{{ entry.content.replace('\r\n','<br />') }}
or
{{ entry.content.replace('\r\n','
') }}
in my template, it will display "hellohello" or "hello
hello" on the page.
So my impression is that the newline characters just aren't being interpreted and displayed by the browser. What am I doing wrong?
Try {{ entry.content|safe }} so Flask/Jinja doesn't escape your HTML.
(Be careful, though, as any user entered content, including script tags, will be output as-is. If you really want to be cautious and only allow tags you might want to do write your own scrubber: Jinja2 escape all HTML but img, b, etc)