Heads up! To view this whole video, sign in with your Courses Plus account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Learn how to transform Markdown text into HTML using a custom filter
Teacher's Notes
-
Documentation for Markdown2 Python library
- Markdown2 on PyPI
- Markdown Syntax Documentation
- Markdown Basics on GitHub
- Documentation on Filters and Auto-escaping
mark_safe(variable)
- Marks the variable as being safe to send directly to the browser without escaping or encoding the contents beforehand.
Markdown
Here's the markdown I used in the video:
## Testing is Amazing!
Learn to test your Python applications with unittest and doctests!
Things you will learn:
- unittest
- doctests
We are almost done with
customizing Django templates.
0:00
In real world scenarios you'll
probably have users pasting long text
0:04
descriptions into your admin site using
Markdown or another plain text format.
0:09
Markdown is what's used on GitHub for
example, for read me files.
0:15
It allows you to easily type text that
will render as html on a webpage, but
0:20
in Django you have to do some preparation
to get that to happen as expected.
0:25
So let's write.
0:31
You guessed it, a custom filter for that.
0:32
First, we're going to install
a Python library called markdown2.
0:37
In your console,
change directories into learning site and
0:41
the run this command,
pip install markdown2.
0:45
Okay.
0:50
Once that finishes running,
open up course_extras.py and
0:51
add import markdown2 to the top.
0:56
Now, just to make sure everything's
installed, let's start our server and
1:00
load our page.
1:04
If we don't get an import error, we know
that everything installed correctly.
1:05
So we'll do python manage.py runserver,
1:10
and then identify our port.
1:16
Great.
1:19
It looks like we are good to go.
1:20
So let's create our function.
1:22
We'll put the console down here.
1:24
And then down here at the bottom,
we'll call our function mark down to html.
1:27
And it's going to take an argument,
1:31
it'll take a markdown text as an argument.
1:36
It will return html, so
we'll call what it returns html_body.
1:40
It's the stuff in the middle
that we need to worry about.
1:47
So let's add a dock string, so
1:50
that everyone knows what this
function is supposed to do.
1:51
So, converts markdown text to html.
1:54
That's pretty straightforward.
2:01
If we look at the documentation for
markdown too.
2:03
We see that it's pretty simple.
2:06
We should be able to just call the mark
down method on our passed in text,
2:08
and it will do all the processing for us.
2:13
I love simple libraries like this
that are really powerful, and
2:16
do something amazing and useful, but
don't require a lot of work on my part.
2:20
So let's add that to our function.
2:25
So we can say that html body is going
to be equal to markdown2.markdown,
2:27
and then we pass in our markdown text.
2:34
So what this will do, is it will
convert our markdown text into html and
2:38
store that result in our variable
html body, which we then return.
2:43
Finally, we need to register our filter,
and this is going to be exactly the same
2:48
as whenever we registered
our time estimate filter.
2:54
The only thing we need to change
is the name of the filter.
2:57
Markdown to html.
3:01
There we go.
3:04
Can you think of a place in
our site where someone might
3:06
enter markdown text instead of
regular html or plain text?
3:09
I can, the course description.
3:13
Sometimes those are longer and
require some formatting.
3:16
So let's create a super user
to log into the admin and
3:19
replace the current course description
with some marked down text.
3:22
So down in your consul,
stop your server with Ctrl+C.
3:27
And then run python
manage.py createsuperuser.
3:31
I'm going to make my name Lacey,
my user name.
3:37
And then I'll set my email address
to Lacey@teamtreehouse.com.
3:40
My password, that's private.
3:47
Okay.
3:51
Let's restart our server, and
3:52
then head into the admin to edit a course
description with some markdown text.
3:55
So up here in our url
we just do /admin and
4:00
then we log in using those
credentials that we just created.
4:05
Here in courses,
I'm gonna change Python testing.
4:10
So right now it just says, learn to test
your Python applications with unittest and
4:14
doctests.
4:18
I'm gonna replace this with some
mark down text that I've created.
4:20
And we'll go over what those should do.
4:24
Okay.
So I've added this header and
4:27
this double pound sign means that
this line testing is amazing,
4:30
should appear inside the header tags.
4:34
Then, these next two lines learn to test
your Python applications with unitest and
4:37
doctest and things you will learn should
each show up inside their own P tags.
4:42
Then when you put a little dash next to
a series of things that are in a list,
4:48
in html,
this should render as an unordered list.
4:54
So now that we've done this,
let's scroll down and save.
4:58
And let's head back into our course.
5:04
When we go to Python Testing,
5:06
it looks like those special mark down
characters just rendered normally.
5:09
They didn't convert.
5:13
Oh, but that's because we
forgot something important.
5:15
We forgot to add this filter that
we created to our description, so
5:18
let's add that.
5:21
We ca go to the course_detail page and
then we can just add our new
5:23
markdown_to_html filter.
5:28
Let's reload.
5:33
Oh, invalid filter.
5:35
Because up here with this load humanize,
we also needed to load our course extras.
5:37
Now we can put load course
extras on it's own line or
5:42
we can just stack it, next to humanize.
5:46
So let's do that to save
ourselves some time.
5:49
Okay, this isn't quite what we expected.
5:51
We're seeing the actual html tags
instead of the rendered html.
5:57
Now this is actually a nice thing
that Django is doing for us.
6:03
It's Django's way of protecting us from
code that might get plugged into our data
6:06
and might be malicious.
6:11
We just need to tell
Django this code is safe,
6:13
meaning that it can render this
html as html, with no problem.
6:16
For that, we can use the safe filter, so
6:21
we can chain safe next
to markdown to html.
6:25
Now, when we reload the page,
we get our nice, friendly rendered html.
6:31
There's a better way to
mark text as safe though.
6:37
We should mark our output
from the filter as safe, so
6:40
that anything that goes through
this filter is marked safe and
6:43
we don't have to keep using the safe
filter over and over again.
6:47
So let's import something called
mark safe into course extras.
6:50
We can lower this console.
6:54
Go back up to the top and
6:57
from django.utils.safestring
we import mark_safe,
7:01
and then we'll just pass our output
into mark_safe as we return it.
7:09
Finally, we can go ahead and
delete the safe filter from our variable.
7:17
Now when we refresh the page,
we have the exact same result,
7:25
which is what we wanted.
7:28
In the real world,
we do a few things differently.
7:29
We would probably have the user select
the format that they were using to submit
7:35
their data, markdown, plain text,
or something else, and
7:39
we'd use the appropriate
conversion filter accordingly.
7:43
We would also add that filter
to all the text content,
7:47
for example, to the step content,
as well as to the course content.
7:51
But for our purposes, we've proven
the concept, and that's enough.
7:56
You need to sign up for Treehouse in order to download course files.
Sign up