How do you display markdown value using jinja2? - python

I process a string on the server using python markdown2 module.
marked_up = ' import sys\n print "hello there"'
marked_up = unicode(markdown2.markdown(marked_up, extras=["fenced-code-blocks"]))
Then, I pass the value through jinja2 to the client:
template_value = {'marked_up': marked_up}
template = JINJA_ENVIRONMENT.get_template('index.html')
self.response.write(template.render(template_value))
In the index.html I try to display this marked value:
<div class="row marketing" id="my_row_mark">
{{ marked_up }}
</div>
The problem is that the text is shown with the html attributes:
<pre><code>import sys print "hello there" </code></pre>
I would like to see only:
import sys print "hello there"
with the proper markdown applied by markdown2.

TL;DR:
Use the |safe filter to prevent your content from getting automatically escaped:
{{ marked_up|safe }}
Jinja2 has a configuration option named autoescape that determines if content in templates should be automatically HTML escaped or not.
By default (if you're using plain Jinja2) autoescaping is disabled. But if your using a framework that integrates Jinja2, autoescape may very well be enabled.
So when autoescaping is enabled, any content you pass into a template will be HTML escaped. Note in this example how content will be escaped, which leads to you seeing the HTML tags in the rendered HTML:
example.py
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('.'),
autoescape=True) # <-- autoescaping enabled
template = env.get_template('index.html')
content = "<strong>bar</strong>"
print template.render(content=content)
index.html
<div>
{{ content }}
</div>
Output:
<div>
<strong>bar</strong>
</div>
You can now prevent escaping for a particular variable by using the |safe filter:
<div>
{{ content|safe }}
</div>
Output:
<div>
<strong>bar</strong>
</div>
For more details, see the documentation on HTML escaping.

Related

Flask , rendering template with additional HTML tags

I have a route:
#app.route("/ticket/<int:ticket_id>")
def ticket(ticket_id):
update_list = get_data(ticket_id)
return render_template('ticket.html', ticket_id=ticket_id, update_list=update_list)
Now update_list contains list of notes with HTML tags included, for example:
update_list[0]
<p> This is my first note </p>
ticket.html:
<h1> {{ update_list[0] }} </h1>
If I try go into http://localhost/ticket/12345 I can see page renders with additional
HTML tags(h1 tag is rendered properly):
<p> This is my first note </p>
Is there a way to make Flask render these additional HTML "<p>" (or any other) tags ?
Thanks!
Adding safe fixed the issue:
<h1> {{ update_list[0]|safe }} </h1>

Django template variable string as html [duplicate]

I use the 'messages' interface to pass messages to user like this:
request.user.message_set.create(message=message)
I would like to include html in my {{ message }} variable and render it without escaping the markup in the template.
If you don't want the HTML to be escaped, look at the safe filter and the autoescape tag:
safe:
{{ myhtml |safe }}
autoescape:
{% autoescape off %}
{{ myhtml }}
{% endautoescape %}
If you want to do something more complicated with your text you could create your own filter and do some magic before returning the html.
With a templatag file looking like this:
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
#register.filter
def do_something(title, content):
something = '<h1>%s</h1><p>%s</p>' % (title, content)
return mark_safe(something)
Then you could add this in your template file
<body>
...
{{ title|do_something:content }}
...
</body>
And this would give you a nice outcome.
Use the autoescape to turn HTML escaping off:
{% autoescape off %}{{ message }}{% endautoescape %}
You can render a template in your code like so:
from django.template import Context, Template
t = Template('This is your <span>{{ message }}</span>.')
c = Context({'message': 'Your message'})
html = t.render(c)
See the Django docs for further information.
The simplest way is to use the safe filter:
{{ message|safe }}
Check out the Django documentation for the safe filter for more information.
No need to use the filter or tag in template.
Just use format_html() to translate variable to html and Django will automatically turn escape off for you variable.
format_html("<h1>Hello</h1>")
Check out here https://docs.djangoproject.com/en/3.0/ref/utils/#django.utils.html.format_html
The safe filter did the work for me.
Using {{data|safe}} includes the html as it is.

Django autoescape is not working in render_to_string(template)?

I am drafting an email template to users when they successfully updated their passwords.
I used {{ autoescape off }} in the template, which is rendered by using render_to_string().
However, the email content shows the HTML angle brackets directly like this:
Hi <span style='color:blue'>user! </span>
Your password is updated successfully!
I am using Django2.0 and my code looks like this:
views.py
from django.core.mail import send_mail
from django.template.loader import render_to_string
def sendmail(request, title)
email_title = title
email_content = render_to_string('template.html',{'username':request.user.username})
recipient = request.user.email
send_mail(
email_title,
email_content,
'myemail#email.com',
[recipient,],
)
template.html
{{ autoescape off}}
Hi <span style='color:blue'>user! </span>
Your password is updated successfully!
{{ endautoescape }}
Is there anything wrong with my code?
Otherwise, is autoescape always on while using render_to_string()?
This has nothing to do with autoescape, which is for rendering variables (it is also a template tag, so you use it with {% autoescape off %}, not {{ autoescape off }}). It is doing nothing at all in your current template.
Your issue is that you're trying to put HTML into the plain text body of an email.
send_mail expects a plain text message body. If you want to have a HTML body then you need to supply a html_message argument:
send_mail(
email_title,
'', # Empty plain text body - not recommended and you should supply a plain text alternative
'myemail#email.com',
[recipient,],
html_message=email_content, # This will render as HTML
)

How to pass html tags with template variable in django?

I try to pass some html tags in server side to front side.
I had programmed like this:
view.py
....
context['tags'] = "<div><h1> Hello </h1></div>"
return render(request, 'test.html', context)
test.html is below:
<body>
{{ tags }}
</body>
the rendering result is,
<div><h1> Hello </h1></div>
But, what I want is
<h1> Hello </h1>
How do I do? I have to in this way.
"<div><h1> {{ tags }} </h1></div>" is not what I want.
Use safe templatetag: {{ tags|safe }} Here is a link https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#safe
Update because of the comments:
If I didn't get your question and you wanted to just remove the div tag just use templatefilter removetags: {{ tags|removetags:"div" }} https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#removetags BUT NOTE it's deprecated since Django 1.8 I recommend you read the reasons and rethink what you want to do...

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