{{ variable|my_filter }}
. And filters with an argument are {{ variable|my_filter: "foo" }}
. You can apply as many filters as you want to a variable, for example, {{ variable|filter1|filter2 }}
. Each of them will be applied in the output that generates the previous one. Let’s create our own filter that will allow us to use Markdown markup in blog posts and then convert the content into HTML code in templates. Markdown is a syntax for formatting plain text that is then converted into HTML. The basics of this format can be found at https://daringfireball.net/project/markdown/basics. First, install the Markdown module in Python using pip
: pip install Markdown==2.6.11
Then edit the blog_tags.py
file and add the following code:
from django.utils.safestring import mark_safe
import markdown
@register.filter(name='markdown')
def markdown_format(text)
return mark_safe(markdown.markdown(text))
Template filters are registered in the same way as template tags. To avoid a function name conflict with the markdown module, the former should be named markdown_format
and the template filter should be named markdown
: {{ variable|markdown }}
. Django excludes HTML code generated by the filters. Django’s mark_sage
function is used to mark which HTML code should be rendered in the standard way. By default, Django will exclude any HTML code before output. The only exceptions are marked variables. This behavior prevents possible output of potentially dangerous code and allows you to create exceptions to return safe HTML code. Now load template tags into the post list and post page templates. Add the following line at the top of the blog/post/list.html
and blog/post/detail.html
templates after the {% extends %}
tag:
{% load blog_tags %}
In the post/detail.html
template, look at the following line:
{{ post.body|linebreaks }}
Replace it with this line:
{{ post.body|markdown }}
Then in post/list.html
, replace this line:
{{ post.body|truncatewords:30|linebreaks }}
To this:
{{ post.body|markdown|truncatewords_html:30 }}
truncatewords_html
filter trims the line after a certain number of words, avoiding unclosed HTML tags.Now open https://127.0.0.1:8000/admin/blog/post/add in your browser and add a post with the following tag.
This is a post formatted with markdown
--------------------------------------
*This is emphasized* and **this is more emphasized**.
Here is a list:
* One
* Two
* Three
And a [link to the Django website](https://www.djangoproject.com/)
Open the browser and see how it is rendered. It should look like this:As you can see in the screenshot, the custom template filters are very handy for formatting. More on this topic here: https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/#writing-custom-template-filters.