Django - safely render HTML in template - django

I am building a django web application where the user can submit text via a tinymce editor.
For that task I use the django-tinymce extension.
The question:
Is it secure to render the HTML in the template using the safe filter like so ? :
{{ richtext | safe }}
If not, how can it be made safe ?

If the html is coming from a reliable source, such as yourself, then it's (most probably) safe. But if you're allowing your site's users to submit their own html markup, then it's not safe.
But sometimes it is necessary to display html markup in django's templates and there's no choice but to use the safe filter. In those cases, the solution is to "sanitize" the html code.
"Sanitizing" means you keep only the safe html tags in the data and remove all the unsafe or unwanted tags (like script or style tags).
For sanitizing the data, you can use the bleach library.
Here's an example (taken from docs):
import bleach
bleach.clean('an <script>evil()</script> example')
# Output -> u'an <script>evil()</script> example'
There's also django app for this library: django-bleach.

Related

Using Quill Editor on a form input in Django.

I want to use Quill Editor on a form input in Django.
From the examples in Quill playground I see that always the container is a div.
How can I make it work with a <textarea> instead of a div, and the text to remain in textarea, to work when I submit the form by Django;
I know there is a django-quill package, but lastest commit was done in 2015, and is reported not working with new Django versions, beside I want to do it more custom.
Quill is working inside a contenteditable div. If you want to make it "look like" a textarea this should be easy using css.
But if you're using Quill, this might be to use rich text, like bold, italic, bullets... And that rich content cannot live inside a textarea that just handles plain text (no text-formatting). That's why its has to stay inside a contenteditabe div.
Your form should, on submit, look for this div content and send it to your backend (either in pure js, or by copy-pasting the html content inside a hidden textarea this time) in html format.

Zurb foundation Interchange with Django templates?

Is Zurb Foundation's Interchange compatible for use with Django templates? I can't see a way to get them to work together, though the issue is just a technical one - Interchange seems to want html file paths, while Django's html templates render inline.
I suppose it would be possible to render the necessary templates each request into temporary files and hand those to Interchange, but that's not a very clean solution and would require a lot of boilerplate. I'm looking for a cleaner solution or for an alternative within Foundation and Django.
No, Foundation's interchange is javascript that runs in the browser within the HTML file produced by Django on your back-end. It's meant to be used for loading static files, mostly media, dependent on the size class of your browser view. E.g. inside and <img> tag:
<img data-interchange="[{% static 'images/my_background_small.png' %}, small], [{% static 'images/my_background.png' %}, medium]>
If you want to serve different HTML to different types of end-devices, you have to add that logic to your Django app's view, so that it uses a different template depending on the client. In general there are a few approaches:
What people do nowadays: Write responsive templates so that the same
HTML is served for mobile and desktop. For the few minor
differences, you can hide/show divs depending on the media class.
Check the device in your middleware and pass it as parameter to your views and templates so you can make decisions on it. Check django-mobile for example
Check the device in your server (apache or nginx) and add an HTTP header to your request that you can parse in your view (e.g. request.META.get('HTTP_MOBILE_SITE','no'). Example here

Render a block through a template that will be added to an existing page as well as it's own

I have a page which is for album/picture management with 2 sections: Albums and Pictures.
When an album is selected the pictures block needs to change via AJAX to reflect the album selected.
This means the rendered pictures block needs to be provided to the Albums page as well as be available as it's own View for the AJAX source.
I understand I could solve this by making the pictures block always render from AJAX even when the album page loads, however I would like to deliver the default album pictures within the initial page load if possible. In order to do that, I'd like to render the pictures block via the same template in the Album page view as is used for the Picture AJAX View.
I'm only familiar with providing templates as a template_name property within an TemplateView object.
I guess I could simply call an instance of PictureView using inclusion_tag, and pull the data I need out of the render_to_response (I haven't tried this yet, I'm just theorizing) however that seems a bit dirty to me. I'm wondering if there's a more elegant solution to this problem?
Thanks!
jQuery, Django templates, JS templating and backbone.js should tie this together.
I would suggest having a dedicated template for the Pages block. Include this template in the Django template for your page.
For dynamic updates use a JS templating library such as included in underscore.js or moustache.js. You can change the template demlimiters used so that they are the same as djangos.
Include the raw Pages block template into a javascript template block - use the django ssi tag.
Use django-tastypie to set up an api that returns the data for Photos as JSON. Your template library can then use data to fill in the template in the JS template block and you can then replace the Photo block with this rendered HTML. Use of backbone.js should ease the tying of DOM elements and JS events.
If I understand your question correctly, I did something similar once with the subsection having its own template file, which only describes that one section of the page. I used the include tag to include it into the page template, so it loaded when the page did and then rendered that template with updated values and replaced it on the page with AJAX when the content was meant to change.
Is that an option for you?

How to access page title in Django templates?

How can I get the page title in the template? I know there are ways to do this with javascript, but I'll prefer a template-tag or a variable if it exists.
The page title is an html element (<title>Title Here</title>), and django has no idea what that is.
Django's templates render the raw HTML text, which a browser parses and only then does the concept of a page title exist for javascript to parse.
If you need it in django, you'd want to ensure django is building that title tag and you would access it in the same way you'd display any other variable in a template.
It's probably best left to the DOM tools since a title might be created in any number of ways. If you absolutely need it in django, I would probably parse the final rendered HTML with an HTML parser like BeautifulSoup.
title = BeautifulSoup(mytemplate.render(Context({}))).html.head.title

How to correctly modify <HEAD> in Django-CMS for custom plugins?

Django-CMS custom plugins and navigation extenders allow to create any content HTML in some part of the HTML . However I frequently have some JavaScripts required for some specific plugins, like a photo album viewer plugin that requires a JS in the .
My current solution is to let the user specify a specific template for that. I could do some checking in the template render() to use a specific placeholder or use placeholder restrictions but that doesn't seem right: It's still in the "body" placeholder.
Any suggestion?
Nothing wrong with including Javascript in the body - in fact, some consider it best practice.