Rich Text Field not returning desired output - python

I'm using CKEditor rich text field for my Django blog app. But not getting the desired output. If I write some heading text, on the front end the output is <h1> Hello </h1>. But I don't want heading tags, I also tried to striptags but in that case, the output is not heading it is simple paragraph text
index.html
{% for posts in post %}
<div>{{posts.content|striptags}}</div>
{% endfor %}
Rich text model
content = RichTextField(blank = True ,null = True)

I guess you want the safe filter, which tells django you know you are doing something a little bit dangerous, and it should not try to protect you.
{% posts.content|safe %}
that will actually render the html (including any malicious javascript a user may have entered (ie i would strongly recomend using a package like bleach or html-sanitizer to only allow specific html tags)

Related

calling django translation values using include tag not displayed

I am using django 1.7.2 and python 2.7.
I have a number of templates that use a number of translated variables.
I thought that it reasonable to place the translated variables in its own page and then use an include tag to place the translated value on the required template pages. But this approach does not work!
Does anyone know why this does not work or a workaround?
Here is what I currently have:
I have added the following include tag on my template pages:
{% include "my_details/summary_details_translations.html" %}
This is the contents of the summary_details_translations.html page:
{% load i18n %}
{% trans "Summary Details" as resume_detail_temp_value %}
The {{ resume_detail_temp_value }} in my template pages do not display a value.
I have tested that the address of the include is correct by adding simple text data to the summary_details_translations.html page, which does display on the template pages.

Limiting the content of TextField in django templates

I am trying to create a blog index page where all the blog post entries are shown. But i want to limit the content of the post body to certain amount (Similar to any blog you see on the internet) so not all the content is visible but when user click on Read More link he can see that particular post in details.
I know how to create page for single article but i am not able to figure out how to limit the post body content. Do i need to change anything in the model or i can do this directly from templates
<h1>{{ post.title }}</h1>
<p>{{ post.post_body }}</p>
Read More
I have declared post body as textfield
post_body = models.TextField()
truncatechars¶
Truncates a string if it is longer than the specified number of characters. Truncated strings will end with a translatable ellipsis sequence (”...”).
Argument: Number of characters to truncate to
For example:
{{ value|truncatechars:9 }}
If value is "Joel is a slug", the output will be "Joel i...".
docs
You can use Built-in Template tag "truncatewords", like this below:
{{ post.post_body | truncatewords:50 }}
This will show the first 50 words of your post.
Here is the Documentation

Jinja2 Default Page Title

I'm attempting to set a default page title for all pages in a Flask application.
I want to insert this into the default layout template. I have a site name in my settings.
<title>{{title}}</title}}
The problem is, I cannot seem to import the site name from the settings to the layout template.
<title>{{settings.SETTING}}</title}}
and similar variations do not work.
Is there an easy way to do this; I don't want to have to set the title with every action in my controller, and the logical way is go from my settings to the template. I just don't see a way right now, any input appreciated.
edit:
I'd prefer not to write an extension, I see another part of my app is using an extension to pull variables into the template, but writing an entire extension is a bit beyond my time investment at the time.
edit:
def page_title(title):
return settings.SITE_NAME
app.jinja_env.filters['page_title'] = page_title
in template:
{{ title | page_title}}
which is something close, i want to set title OR override with a default and that is a first step that works
Use a block:
<title>{% block title %}{{ settings.SETTING }}{% endblock %}</title>
Then you can simply override that block in a template inheriting from your base template if you want to change the title.
{% block title %}your custom title{% endblock %}

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 - Store unescaped html in model

I am trying to store raw, unescaped HTML inside one of my Django models for display on my home page. However, when I store it in a TextField it gets escaped, and ends up just being displayed as raw text. How can I store raw HTML in a Django model?
** EDIT **
It seems as if its not getting escaped in the model layer, but in the Template layer. Is there a special tag I should use? I checked the value in the shell and it's just fine, but for some reason when i did {{ block.html } (html is the attribute of the block object that stores the actual HTML) in the template, it comes out like this:
<p>This is a <strong>very</strong> <em>important</em> <span style="text-decoration: underline;">block</span></p>
<p style="padding-left: 30px;">it has very significant content!</p>
You can use the safe filter to present unescaped text, or escape filter to present escaped text. You can also use autoescape tag to set a block. ({% autoescape on %} or {% autoescape off %})

Categories

Resources