How does Django handle escaping when I use a TinyMCE editor? - python

How do I display only bolds, italics, and all the other non-security issue HTML on the page?

Sanitizing HTML is a pretty hard problem to get right. Spammers and other nasty people come up with new ways to smuggle HTML through sanitation all the time. The safest option is to define a white list of harmless tags and rigorously filter out all other tags with a true HTML parser (not with regular expressions).
There are a couple of template tags and filters on djangosnippets.com, e.g. this or this one. When selecting a filter, pay attention that it uses a white list and an HTML parser like lxml.html (preferably lxml.html.clean) or BeautifulSoup.

Probably it makes more sense to configure TinyMCE that way the user can only enter elements you allow him. TinyMCE has a powerful set of rules for that. If you are using django-tinymce see this for setting TINYMCE_DEFAULT_CONFIG to your desired options.

To display all HTML (no-escaping) you can use safe filter
{{ var|safe }}
In your case, if you want to escape everything except certain tags, you can write you own filter that does that:
{{ var|mysafe }}
Read about it here: http://docs.djangoproject.com/en/dev/howto/custom-template-tags/
The algorithm of the filter could be:
Escape everything
Unescape only those tags that are
allowed (by using .replace or
regilar expressions)

Related

Filter safe does not work on the shy tag issue

I have a problem with breaking words in the right place at the Django template. Appears ­
I'm trying to filter safe, but it does not work.
Here is my code:
<div class="my_class">
<h3>{{ object.title|safe }}</h3>
</div>
From the doc here:safe
safe
Marks a string as not requiring further HTML escaping prior to output. When autoescaping is off, this filter has no effect.
And Django's templating engine does escaping automatically, look When should I use escape and safe in Django's template system?

serving i18n js using babel, django, & jinja2

Using django, with jinja2 for rendering & babel for message extraction
I have some js files that need to be internationalized. I haven't been able to figure out a syntax for extracting messages from them which would also let jinja2 render them. Either jinja2 has to learn to read an extractable syntax, or I have to extract from something jinja2 can render. (Or, do this another way entirely)
Extracting
If I mark messages in the js with
gettext('message')
It extracts just fine.
Rendering
But jinja2 won't replace gettext calls in js (I'm rendering the js templates with jinja2 before returning them) - it needs something like
{% trans %}message{% endtrans %}
But, that syntax can't be used to extract messages.
Babel is using the function extract_javascript from babel.messages to extract messages, which doesn't look equipeed to handle this type of tag.
Well, it looks like I can just do:
{{gettext("message")}}
(without defining gettext)
in the JS and babel will extract & jinja2 will replace it ok.
Watch out for quotes, though. You can't do:
'{{gettext("message")}}'
because extract_javascript will not read it. But, you can just put the quotes inside, as long as you render them safely:
{{gettext("'message'")|safe}}
So have your translators make sure to leave quotations wherever they find them in the original.

django strips out img tag in the text

I'm using django to make an online testing system, and I want to render a piece of text from database into the page. The text may have variety numbers of tag. When the page is rendered, it strips out the tag and display like this
< img src="{{STATIC_URL}}img/2003/p1q71.jpg" >
instead of displaying image. Any solution for this?
Read about the built-in safe filter.
Django does not consider data from the database to the "Safe".
It always "escapes" any tag-like content in database data to prevent HTML Script Injection attacks.
You want to mark the content you are pulling out of the DB as safe when you use it in your template.
{{ content_from_db|safe }}
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#std:templatefilter-safe

Display Text in Template?

I have a text field in my model that contains markdown text. I need to convert the text to html and show it in my .pt template. what is the best way to do it?
I realise that I can add a method to my model that converts the field and returns HTML, and then call the method from my template, but can I do it without this extra method, by using only the markdown field in my template similarly to Django's?
{{ mytext|markdown:"safe" }}
Plone, which uses TAL for it's templating engine and can use StructuredText, reStructuredText, and other rich text formats, does all the rendering to HTML outside TAL. So you might be barking up the wrong tree in the approach you're going for.
That said, TAL has a somewhat extensible "expression" system which is why you can have path expressions (the default) or python expressions. In the zope world, which includes plone, there's a page composition system called content providers, so someone implemented a provider tal expression. So maybe you can look at that:
tales.py
configure.zcml
The structure keyword is still your easiest bet.
<div tal:replace="structure view/getMarkdown">rendered markdown</div>
But structure is a special case keyword and not an extensible part of page templates.

Django template filters, tags, simple_tags, and inclusion_tags

This is more of a general question about the distinctions between these four different kinds of django tags. I just read the documentation page on template tags:
http://docs.djangoproject.com/en/dev/howto/custom-template-tags/
But I'm finding it difficult to know when I should use one variation over another. For example, what can a template tag do that a simple_tag cannot? Is a filter limited to manipulating strings only and is that why the documentation says that template tags are more powerful because they can "do anything"?
Here is my perception of the distinctions:
template filters: only operate on strings and return strings. No access to models?
template tags: access to anything you can access in a view, compiled into nodes with a specified render function (it seems like the only advantage is that you can add variables to the context?)
simple_tags: take strings and template variables and returns a string, you are passed the value of the template variable rather than the variable itself (when would you ever want the variable itself over the value?)
inclusion tags: allow you to render arbitrary extra templates
Can someone give an example outlining when I would want to use one of these over another?
Thanks.
Template filters can operate on any object (and at most two at once). They're just functions that take one or two arguments. e.g.
# filter implementation
#filter
def myfilter(arg1, arg2):
....
# usage in template
{{ arg1|myfilter:arg2 }}
They are limited in that they cannot access the template context, and can only accept a limited number of arguments.
Use case: You want to use modify one of the variables in the context slightly before printing it.
Template tags can change the way the rest of the template is parsed, and have access to anything in the context in which they are used. They're very powerful. For example I wrote a template tag that subclasses {% extends %} and allows a template to extend different templates based on the current User.
You can easily recognise template tags when they are used, because they around surrounded in {% and %}.
Use case: You want to perform some logic that requires Python code and access to the template context.
Inclusion tags are still template tags, but Django provides some helpers (i.e. the #inclusion_tag decorator) to make it easy to write template tags of this kind.
Use case: You want to render one template into another. For example you may have an advertisement on your site that you want to use in different places. It might not be possible to use template inheritance to achieve what you want, so rather than copy/paste the HTML for the ad multiple times, you would write an inclusion tag.
The reason why you would use an inclusion tag over the existing {% include %} template tag, is that you may want to render the template with a different context to the one you are in. Perhaps you need to do some database queries, to select the correct ad to display. This is not possible with {% include %}.
Simple tags like inclusion tags, simple tags are still template tags but they have limited functionality and are written in a simplified manner. They allow you to write a template tag that accepts any number of arguments (e.g. {% mytag "some str" arg2 arg3 %} etc) and require you to only implement a function that can accept these arguments (and optionally a context variable to give you access to the template context.
Essentially they're an upgrade from template filters, because instead of accepting only 1 or 2 arguments, you can accept as many as you like (and you can also access the template context).

Categories