How to escape {{ or }} in django template? - python

Django treats {{ var }} as some variable in its template. How can I escape {{ var }} or {{ or }} such that django does not treat it as variable.
<p>"{{ some text }}"</p> Should prints exactly the same.

Django 1.5 introduced {% verbatim %} template tag. It stops template from parsing contents of this tag:
{% verbatim %}
{{ var }}
{% endverbatim %}
will be rendered as:
{{ var }}

I believe you are looking for the templatetag template tag.
As the linked-to doc states,
Since the template system has no concept of "escaping", to display one of the bits used in template tags, you must use the {% templatetag %} tag.
For example:
<p>"{% templatetag openvariable %} some text {% templatetag closevariable %}"</p>
will appear as so:
<p>"{{ some text }}"</p>

Edit: I don't really recommended this because it's not very clean, but it's still an option.
I was searching for one that I could use with JQuery Templates and figured a way to do it without tags or filters. This is as short as I could get it:
{{ "{{ any text }" }}}
Is printed as:
{{ any text }}
Why it works? Any text within {{}} is displayed as is, as long as it doesn't have two closing braces }} in a row. Then there are three brackets in a row, django interprets two first ones as end of the variable leaving one additional closing brace.

You can try escaping with html character escapes like:
{ = {
} = }
<p>"{{ some text }}"</p>
Update
In case anyone is trying to use the actual tags for javascript, verbatim is a better solution:
Stops the template engine from rendering the contents of this block tag.
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}

if you simply need to use {{ }} as a variable for template framework like angularjs, then following maybe simpler:
in your <app path>/templatetags/ngvar.py , add
from django import template
register = template.Library()
#register.simple_tag
def ngvar(var_name):
return "{{%s}}" % var_name
and in template, do
{% load ngvar %}
{% ngvar "variable name" %}
if ngvar.py is the first template tag, then make sure to add __init__.py file to the templatetags directory

Another option would be to add a word joiner (zero width no-break space) between each curly bracket:
<p>"{⁠{ some text }⁠}"</p>

Although the above answers can solve the original problem, I add some hack around here for those who are scratching their heads like me.
Some times, we want to render a single brace followed by a variable. For example, in BibTeX, there may be something look like this:
#MISC{hu2012-spectral,
author = {Hu, Pili},
title = {Spectral Clustering Survey},
howpublished = {GitHub, https://github.com/hupili/tutorial/tree/master/spectral-clustering},
month = {May},
year = {2012}
}
Those bib fields come from template variables. If you write
title = {{{title}}},
jinja can not compile and raise an error. If you write
title = { {{title}} },
there will be extra blanks. The hack around is to store '{' and '}' as variables and use later.
{% set lb = '{' %}
{% set rb = '}' %}
...
#MISC{{lb}}{{ meta.bib_key }},
author = {{lb}}Hu, Pili{{rb}},
title = {{lb}}{{ meta.title }}{{rb}},
howpublished = {{lb}}GitHub, https://github.com/hupili/tutorial/tree/master/{{ auto.path}}{{rb}},
month = {{lb}}{{ meta.month }}{{rb}},
year = {{lb}}{{ meta.year }}{{rb}}
}
This looks clumsy but it is the best I find so far. If you have a cleaner solution, please tell me.

This template tag (designed for use with jQuery Templates) might do the trick. It let's you wrap content you don't want Django to interpret as variables with a template tag.

it can be solved by avoing adjacent angular backets, if its inside javascript code then you can write
'{'+'{address.'+key+'}}'
I used this to print jinja variables into another template,using javascript.

Jinja, which is what is being used for the templates, offers several suggestions for escaping here. What has worked best for me is using something like "{% raw %}{{ some text }}{% endraw %}"

Related

How I do convert an md file to HTML and pass the variable into HTML file [duplicate]

Is there any way to completely turn off django auto_escaping when rendering a template within the view code (for an email for example):
from django.template import Context, Template
subject_template_string = "Hi {{ customer.name }}"
subject_template = Template(subject)
context = Context({'customer':MyCustomerModel.objects.get(pk=1)})
subject = subject_template.render(context)
If customer.name is something like "Jack & Jill" - the subject looks like "Hi Jack &\amp; Jill" (without the backslash!)
is there something like
subject = subject_template.render(context, autoescape=False)
edit: The actual templates are created by the client in the database, I'm hoping to avoid having to say add |safe to all templates where this might happen...
Disabling it globally is usually a bad idea since you can easily forget it. I would recommend using the templatetag to disable it for that portion of your template instead.
Something like this:
{% autoescape off %}
This will not be auto-escaped: {{ data }}.
Nor this: {{ other_data }}
{% autoescape on %}
Auto-escaping applies again: {{ name }}
{% endautoescape %}
{% endautoescape %}
How about using mark_safe:
Explicitly mark a string as safe for (HTML) output purposes. The
returned object can be used everywhere a string or unicode object is
appropriate.
It marks a string as safe, so, you should take customer.name out and pass to the template:
from django.utils.safestring import mark_safe
customer = MyCustomerModel.objects.get(pk=1)
context = Context({'customer_name': mark_safe(customer.name)})
subject = subject_template.render(context)
Though, control what is safe or not is better to do inside the template itself, that's why using autoescape should be preffered.
Use Django's autoescape tag:
{% autoescape off %}
{{ body }}
{% endautoescape %}
for more info, check out the docs here.
This is untested, but based on source code review it looks like the context object can take autoescape as a key.
context = Context({'customer':MyCustomerModel.objects.get(pk=1), 'autoescape': False})
subject = subject_template.render(context)
That said, that's a pretty sweeping change. If you know what values the templates might be looking for, it's probably better to use mark_safe on those values and pass in the predefined options. That would have the added benefit of not risking the possibility of the client template calling a method with side effects on the customer. The first time someone writes a template and puts in {{ customer.delete }}, you have a problem.
Just came back to answer my own question with a simple solution, and there were already 4 answers.. thanks.
This is what I've gone with:
subject_template = Template(u'{%% autoescape off %%}%s{%% endautoescape %%}' % email.subject)

How to use jinja tag inside jinja tag

This is my code:
{% if {{post.author.profile.image.url}} is None %}
When I run this code I get an error
Could not parse the remainder: '{{post.author.profile.image.url}}' from '{{post.author.profile.image.url}}'
How to solve this? And how to use a template tag inside a template tag
Use the value of expression directly, you shouldn't wrap it inside braces:
{% if post.author.profile.image.url is None %}
...
{% endif %}
abdusco's already answered the first part of your question ("how to solve this").
wrt/ the second part:
how to use a template tag inside a template tag
The simple answer is: you can't, period. Why it's not possible becomes rather obvious once you understand how the template system works, and that would be mostly useless anyway (if you find yourself trying to use a tag within a tag then you're doing it wrong and there's a better way, really).
NB: when I say you can`t nest tags, I mean that you can't do this:
{% sometag arg={% some_other_tag %} %}
Now in your example, what you're trying to do is not "using a tag inside a tag", but using a context variable within a tag, and this is of course possible (else the template language would be rather hard to use), as shown in abdusco's answer. And you can also use filter expressions (apply a filter to a context variable) here, ie {% mytag some.variable|upper %}, at least if the template tag is correctly implemented.
The first question has already answered. Regarding to this one:
And how to use a template tag inside a template tag
Short answer: you can't. Long answer: you can with help of the 'block assignment' tag ( http://jinja.pocoo.org/docs/2.10/templates/#block-assignments ) :
{% set somevar %}
... any number of tags here {{ post.author.profile.image.url }} ...
{% endset %}
...
{% if somevar is None %} ... {% endif %}
You can also (since Jinja2 2.10) apply filter to the assignment:
{% set somevar | default('Empty') %}
... any number of tags here {{ post.author.profile.image.url }} ...
{% endset %}

Django: Use ugettext_lazy in templates

Hello I want to know if I can use ugettext_lazy as _ in the templates of django because I want to replace the tags of {% trans %} and {% blocktrans %} because I don't want to make the messages.
I want to do something like this:
<h1>_('hello')</h1>
Instead of this:
<h1>{% trans 'hello' %}</h1>
Thanks
It's not possible to call any function from a template that takes any arguments. You have to write either tag or filter but I would suggest you to stick with the trans block.
I want to say that <h1>_('hello')</h1> this functionality not possible in django template.
but we have another way of like this with custom templatetag that support your way for translate string in template
{% some_tag _("Page not found") value|yesno:_("yes,no") %}
above added string will work as translation in django.
Read from django documentation https://docs.djangoproject.com/en/1.11/topics/i18n/translation/#string-literals-passed-to-tags-and-filters

Any way to add a new line from a string with the '\n' character in flask?

I was playing around with flask when I came across an odd problem with the '\n' character. it dosen't seem to have an effect in my browser, I tried putting in there but it didn't work, any ideas?
from flask import Flask
from flask import render_template
test=Flask(__name__)
#test.route('/')
def root():
str='yay\nsuper'
return str
test.run(debug=True)
So it turns out that flask autoescapes html tags. So adding the <br> tag just renders them on screen instead of actually creating line breaks.
There are two workarounds to this:
Break up the text into an array
text = text.split('\n')
And then within the template, use a for loop:
{% for para in text %}
<p>{{para}}</p>
{% endfor %}
Disable the autoescaping
First we replace the \n with <br> using replace:
text = text.replace('\n', '<br>')
Then we disable the autoescaping by surrounding the block where we require this with
{% autoescape false %}
{{text}}
{% endautoescape %}
However, we are discouraged from doing this:
Whenever you do this, please be very cautious about the variables you are using in this block.
I think the first version avoids the vulnerabilities present in the second version, while still being quite easy to understand.
Newlines only have an effect on HTML rendering in specific cases. You would need to use an HTML tag representing a newline, such as <br/>.
def root():
str='yay<br/>super'
return str
In case someone end up here like me, and doesn't want to use {% autoescape false %}, for safety reasons, nor braking up the text which might be inconvenient in some cases, I found a good alternative here:
from flask import Markup
value = Markup('First line.<br>Second line.<br>')
and then in the jinja template:
{{ value }}
I come late to the party, but here's my solution.
HTML has a <pre> tag which can prove useful in this situation.
<pre>{{ your_text }}</pre>
This tag tells the browser not to automatically adjust spacing and line breaks.
To learn more about this tag check this guide out.
works for me and preserves security
I would suggest <br> rather than <p>
{% for para in text %}
{{para}}<br>
{% endfor %}
then result is less bulky
Easiest way to do this
Create your template filter
#app.template_filter(name='linebreaksbr')
def linebreaksbr_filter(text):
return text.replace('\n', '<br>')
Add this to your template
{{ someText|linebreaksbr }}
This will replace every "\n" character in your text with <br>.

Django template question: how to output just the text if the variable has html in it?

I have a lot of variables that has html in them. For example the value of a variable called {{object.name}} is the following:
Play this hot game and see how <b>fun</b> it is!
Is there a filter that can be applied on the variable that will give me just the text:
Play this hot game and see how fun it is!
Without the text being linked or the html being replaced by htmlentities. Just the text?
striptags filter removes all html
{{object.name|striptags}}
You have 3 options to strip the html code:
Using "safe" filter in your template:
{{ object.name|safe }}
Using "autoescape" tag in your template:
{% autoescape off %}
{{ object.name }}
{% endautoescape %}
or declaring it as "safe" in your python code:
from django.utils.safestring import mark_safe
name = mark_safe(name)

Categories

Resources