Django Blog #29: Creating Your Own Template Filters

by Alex
Django Blog #29: Creating Your Own Template Filters
Django has many different built-in filters that allow you to modify variables in templates. These are Python functions that take one or two parameters: the value of the variable it will be applied to and an optional argument. They return a value that can be mapped or become another filter. A filter looks like this {{ 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 }}
The 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:Django Blog #29: Creating Your Own Template FiltersAs 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.

Related Posts

LEAVE A COMMENT