Jinja 2 safe keyword - python

I have a little problem understanding what an expression like {{ something.render() | safe }} does .
From what I have seen, without the safe keyword it outputs the entire html document, not just the true content.
What I would like to know, is what it actually does, how it functions .

The safe filter explicitly marks a string as "safe", i.e., it should not be automatically-escaped if auto-escaping is enabled.
The documentation on this filter is here.
See the section on manual escaping to see which characters qualify for escaping.

Normally text is HTML-escaped (so <b> would be written out as <b>, which would render as <b>).
When you put |safe after something, you're telling the template engine that you have already escaped the text yourself, i.e. "it's safe to render this directly". So it will not do that encoding for you.
For more information: http://jinja.pocoo.org/docs/templates/#html-escaping

For anyone coming here looking to use the safe filter programmatically: wrap it in a markupsafe.Markup class, on which Jinja2 depends on.

Expanding on #data's answer, here's an example of using markupsafe.Markup:
import markupsafe
vals = {}
vals["name"] = markupsafe.Markup("<b>Duck</b>, Donald")
html = template.render(vals)
The resulting HTML will show Donald's last name in bold wherever the template contains {{name}}.

You can go this way
post.body is the variable that is getting the data from the database or any file.
{{ post.body | safe }}
I hope you will get it.

Related

Django / Python make newline with '\n'

I'm quite new to using Django, so please be gentle, if this is a stupid question.
I'm trying to play with some stock-information in Python/Django. I'm getting the stock-rates from Yahoo Finance (with urllib). Whenever I get some stock-information, then I will get it like this (yep, it's one long string):
[b'Date,Open,High,Low,Close,Volume,Adj Close\n2014-12-01,26.16,26.22,25.85,26.02,48967100,25.54\n2014-11-28,26.80,26.90,26.44,26.49,31185200,26.00\n2014-11-26,26.89,26.97,26.78,26.87,19289700,26.38\n2014-11-25,27.01,27.03,26.84,26.86,28028000,26.37\n']
I then send it to a template with Django, using
to_be_returned = RequestContext(request, [[DICTIONARY_WITH_VARIABLE]])
and then
return HttpResponse(template.render(to_be_returned)
Is there a way, to get Django to beautify the long string for me? So I don't have to manipulate the string and replace all \n with <br />, in order for me to be able to read it easier? And what does the [b' ... '] mean (that contains the entire result?
Thanks for your assistance.
Use the linebreaksbr template filter:
{{ my_string_with_n|linebreaksbr }}
b'...' is a python3 byte string literal.
You do not attached a template.
Wrap out tag with
<pre></pre>
You can add html tag to the strings that you write in the response
For example :
response2.write('</br></br>List of Courses : ')

rendering of textfield and charfield chomps out extra whitespace (Django/Python)

I've noticed that my template is rendering my model.CharField and model.TextField without any excess whitespace.
For example, if I enter data such as...
This is a test
to see what happens.
The rendered object field will appear as...
This is a test to see what happens.
Is this an intentional feature of Django or have I missed some filter or parameter somewhere?
I've checked the field itself with some debug code (print object.field) and it does contains the extra whitespace, so the problem is in the rendering side.
How can I allow the user to enter paragraphs of data in TextFields? How can I preserve the whitespace that the user may have entered?
As you can see even in StackOverflow your spaces do not display, this is from the source of your question:
This is a test
to see what happens.
Will save in the database as:
This is a test\n\n\nto see what happens.
You have to problems when rendering as html:
Extra spaces between words are stripped on display by the browser, unless it is between <pre></pre> tags
Linebreaks will be rendered as plain text linebreaks, which do not display in the browser unless between <pre></pre> tags.
For spaces, you can use such a template filter to replace them with their html entity equivalent: .
To convert database linebreaks in HTML linebreaks, use linebreaksbr built-in filters. For example, if {{ foo }} is: test\nbar, then {{ foo|linebreaksbr }} will render: test<br />bar
Create a "templatetags" folder in some of your apps with an __init__.py file in it.
Save the snippet for example in someapp/templatetags/replace_tag.py
Load the template filter in the template as such {% load replace_tag %}
Combine replace and linebreaksbr as such: {{ foo|linebreaksbr|replace:" "," " }}
You can also make your own template filter that will process the text into the HTML you need. In any case, refer to the custom template filter documentation for complete information.

Django and wrap lines problem

I've a problem from many years.
The problem is a long text not separated by white spaces in a div. No wrap is applied and it breaks all layout.
How can I fix in django in a good way?
This is what I see:
As I understand the question it is HTML-side problem, not django-side. For HTML solution look How to word wrap text in HTML?. If you still want to wrap text in python code, textwrap.wrap will help you.
Also there is convenient template tag for this: wordwrap. It uses django.utils.text.wrap function which seems more suitable for using in Django projects.
This was bugging me as the built-in word-wrap template tag should have just worked. Instead use this...
{{ value|wordwrap:50|linebreaksbr }}
or
{{ value|wordwrap:50|linebreaks }}
depending if you want <br> or <br> and <p> tags
I don't know if it helps, but an approach could be creating a new filter based on truncatewords filter.
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#truncatewords
Code looks very simple:
def truncate_filter(value, maxlen):
if len(value) <= maxlen:
return value
return value[:maxlen-2] + '..'
Another ideia is using: {{ username|stringformat:".10s" }} to truncate in 10 characters.
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#stringformat

Including HTML variable in Django template without escaping

I have html encoded text which reads like this:
RT #freuter...
I want this displayed as html but I am not sure if there is a filter which i can apply to this text to convert the html-encoded text back to html ...
can someone help?
As Daniel says, use the {{ tweet|safe }} filter in the html, or mark it safe from the views.
Use django.template.mark_safe()
Try the |safe filter if you want to render all HTML.
See: How do I perform HTML decoding/encoding using Python/Django?
I think this answers your querstion.

How do I make django's markdown filter transform a carriage return to <br />?

How can I change the default behavior in the markdown filter so that it transforms a newline to a br tag?
I don't think messing around with the newline syntax is a good idea ...
I agree with Henrik's comment. From the markdown docs:
When you do want to insert a <br /> break tag using Markdown, you end a line with two or more spaces, then type return.
Yes, this takes a tad more effort to create a <br />, but a simplistic “every line break is a <br />” rule wouldn’t work for Markdown. Markdown’s email-style blockquoting and multi-paragraph list items work best — and look better — when you format them with hard breaks.
Have you looked at the other Django markup options, textile and restructuredtext? Their syntax might suit you better.
but if you still want to ...
A rough and ready method is to chain the markdown and linebreaksbr filters.
{{ value|markdown|linebreaksbr }}
This runs the markdown filter, then the linebreaksbr filter, which replaces \n with <br />. You'll probably end up with too many linebreaks, but that might be better for you than too few.
If you a better solution than that, you could
Write a custom filter, as John suggests in his answer.
Dive into the the python-markdown library, which Django uses, and write an extension that implements your desired newline syntax. You would then use the extension with the filter
{{ value|markdown:"linebreakextension" }}
EDIT: As of the end of June, 2011, the extension below is now included with Python Markdown.
Here is a Markdown extension that I wrote and am currently testing on my site to do exactly what you want:
"""
A python-markdown extension to treat newlines as hard breaks; like
StackOverflow and GitHub flavored Markdown do.
"""
import markdown
BR_RE = r'\n'
class Nl2BrExtension(markdown.Extension):
def extendMarkdown(self, md, md_globals):
br_tag = markdown.inlinepatterns.SubstituteTagPattern(BR_RE, 'br')
md.inlinePatterns.add('nl', br_tag, '_end')
def makeExtension(configs=None):
return Nl2BrExtension(configs)
I put this in a file called mdx_nl2br.py and put it on my PYTHONPATH. You can then use it in a Django template like this:
{{ value|markdown:"nl2br" }}
If you'd like to use it in regular code, you can do something like this:
import markdown
md = markdown.Markdown(safe_mode=True, extensions=['nl2br'])
converted_text = md.convert(text)
Here is the starting point in the docs for using and writing extensions.
You can override default MARKDOWN_DEUX_STYLES with adding "break-on-newline": True in extras settings :
MARKDOWN_DEUX_STYLES = {
"default": {
"extras": {
"code-friendly": None,
"break-on-newline": True,
},
"safe_mode": "escape",
}
}
Documentation of python-markdown2:
break-on-newline: Replace single new line characters with when
True.
You could write a custom filter that calls markdown, then does replace on its output.
There appears to be a linebreaks filter that converts \n characters to either <br> or <p>.
See linebreaks or linebreaksbr.

Categories