I am working on a Django project and would like to take markdown texts, convert them to HTML, and then display them on the browser. I did some research and tried different ways, but none worked as I wanted.
This is my code:
Python:
class HTMLFilter(HTMLParser):
text = ""
def handle_data(self, data):
self.text = data
def display_entry(request, entry):
if util.get_entry(entry.capitalize()) != None:
markdowner = Markdown()
data = markdowner.convert(util.get_entry(entry.capitalize()))
html = HTMLFilter()
html.feed(data)
body = html.text
return render(request, "encyclopedia/display.html", {
"title": entry,
"body": body
})
else:
return render(request, "encyclopedia/error.html", {
"entry": entry.capitalize()
})
This is how the function (get_entry()) from the util module looks like:
def get_entry(title):
try:
f = default_storage.open(f"entries/{title}.md")
return f.read().decode("utf-8")
except FileNotFoundError:
return None
I use the python-markdown2 package to convert markdown language to HTML and it works perfectly. Below is an example of the text that was converted into HTML.
<h1>Django</h1> <p>Django is a web framework written using <a href="/wiki/Python">Python</a> that allows for the design of web applications that generate <a href="/wiki/HTML">HTML</a> dynamically.</p>
My biggest challenge is displaying this text as normal HTML to the browser. This is what my HTML file looks like:
{% extends "encyclopedia/layout.html" %}
{% block title %} {{ title }} {% endblock %}
{% block body %}
{{ body }}
{% endblock %}
After using HTMLParser from html.parser I get these results:
Django Django is a web framework written using Python that allows for the design of web applications that generate HTML dynamically.
This is not what I want as it completely ignores headings, links, and other important HTML tags.
I did try others ways but did not work as I expected.
Thank you in advance.
CodePudding user response:
You could change your template like this to render HTML strings using safe
filter
{% extends "encyclopedia/layout.html" %}
{% block title %} {{ title }} {% endblock %}
{% block body %}
{{ body |safe }}
{% endblock %
for more info https://docs.djangoproject.com/en/4.0/ref/templates/builtins/#std-templatefilter-safe
CodePudding user response:
There is no need for a HTML parser, as ou already get HTML from the markdown library.
def display_entry(request, entry):
entry_content = util.get_entry(entry.capitalize())
if entry_content != None:
markdowner = Markdown()
body_html = markdowner.convert(entry_content)
return render(request, "encyclopedia/display.html", {
"title": entry,
"body": body_html
})
else:
return render(request, "encyclopedia/error.html", {
"entry": entry.capitalize()
})
In your template you have to use the safe
filter to prevent django from escaping your string.
Django Docs: https://docs.djangoproject.com/en/4.0/ref/templates/builtins/#std-templatefilter-safe
{% extends "encyclopedia/layout.html" %}
{% block title %} {{ title }} {% endblock %}
{% block body %}
{{ body|safe }}
{% endblock %}