4

I am having trouble with markdown on my Django application. I am writing a blog from a tutorial, and want markdown in my posts. I installed Markdownx for Django, and it almost works.

I have issues when it comes to code blocks. The markdown looks different in the admin page than it does in the rendering of the html page. I would like my code blocks to appear as they do on stackoverflow and github. Instead, when I do the code block formatting with the three ```, I get red text.

Below are my files for the application I am asking about:


project/urls.py

from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path('admin/', admin.site.urls),
    path('projects/', include('projects.urls')),
    path('blog/', include('blog.urls')),
    path('markdownx/', include('markdownx.urls')),
]

urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)


project/settings.py

...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'projects',
    'blog',
    'markdownx',
]
...


app/models.py

from django.db import models
from markdownx.models import MarkdownxField
from markdownx.utils import markdownify

class Projects(models.Model):
    title = models.CharField(max_length=100)
    short_description = models.TextField()
    long_description = MarkdownxField()
    project_link = models.URLField(max_length=250)

    def formatted_markdown(self):
        return markdownify(self.long_description)


app/admin.py

from django.contrib import admin
from projects.models import Projects
from markdownx.admin import MarkdownxModelAdmin

class ProjectsAdmin(admin.ModelAdmin):
    pass

admin.site.register(Projects, MarkdownxModelAdmin)


app/views.py

from django.shortcuts import render
from projects.models import Projects

def project_index(request):
    projects = Projects.objects.all()
    context = {
        'projects' : projects
    }
    return render(request, 'project_index.html', context)

def project_detail(request, pk):
    project = Projects.objects.get(pk=pk)
    context = {
        'project' : project
    }
    return render(request, 'project_detail.html', context)


app/templates/project_detail.html

{% extends "base.html" %}
{% load static %}

{% block page_content %}
<h1>{{ project.title }}</h1>
<div class="row">
    <div class="col-md-4">
        <h5>About the project:</h5>
        <p>{{ project.formatted_markdown|safe|linebreaks }}</p>
        <br>
        <h5>Project Link</h5>
        <a href="{{  project.project_link }}" class="btn btn-primary" >Github</a>
    </div>
</div>
{% endblock %}

This first image is the admin page view.

Admin page view


This second image is the template html page view.
Template page view

ChairMane
  • 55
  • 6

1 Answers1

2

You need to enable the correct Markdown extensions and possibly supply some CSS.

As a reminder, fenced code blocks (blocks deliminated with triple backticks ```) are a non-standard feature. According to the documentation, Markdownx uses Python-Markdown to parse the Markdown text and Python-Markdown only supports the standard Markdown features by default (as defined here). Therefore, you need to enable the fenced_code extension to properly parser fenced code blocks.

You will also need to enable the codehilite extension if you want your codeblocks to be highlighted. You will also need to install the pygments package which codehilite uses. You will also need to provide the CSS to define the styles (colors) for the highlighted code. GitHub user richeland has provided a number of different CSS style sheets which work with Pygments along with a preview of each theme.

According to the documentation, Markdownx has a MARKDOWNX_MARKDOWN_EXTENSIONS setting for enabling extensions. Therefore you may need to add the following to your settings.py file:

MARKDOWNX_MARKDOWN_EXTENSIONS = ['fenced_code', 'codehilite']

To install pygments run the following command:

pip install pygments

Then after selecting the highlighting theme you prefer, copy the appropriate CSS to your files and include a link to it in your templates.

Waylan
  • 37,164
  • 12
  • 83
  • 109
  • Thank you for the answer, it definitely helped! Although, it still doesn't work. I looked into the documentation a little further and it seems some of the documentation sites are offline. I managed to find that `MARKDOWNX_MARKDOWN_EXTENSIONS = ['markdown.extensions.codehilite']` looks like that instead. Still that didn't work, though. I installed pygments, but not sure where to place the css files, so I placed them in my static directory. I will look into this further and try different things. You have guided me in a direction and I appreciate it! – ChairMane Apr 10 '20 at 05:39
  • Did you add links to the CSS files in your page templates? The CSS won't do anything if you don't link to it. – Waylan Apr 11 '20 at 19:04
  • Note that while not wrong, `markdown.extensions.codehilite` is an older, deprecated way to enable an extension. With newer versions of Markdown `codehilite` will work just fine. – Waylan Apr 11 '20 at 19:07
  • This is kind of embarrassing, but I don't know if I'm adding the CSS files correctly. Here is how I inlcuded the chosen css file from that link you gave me: ``. This line is in my applications template, which is what I show in my post. I also have my static directory in my projects root, which has the `default.css` stylesheet in it. I've been trying to look online for possible solutions to this, and I see a ton of older documentation, but no newer documentation. – ChairMane Apr 12 '20 at 00:22
  • That looks right to me, but then I haven't used Django in years so I can't comment on the `{% static %}` thing. To ensure everything is correct, fire up the dev server, load a page in our browser and use the browser's dev tools to confirm that the file is properly referenced and that the rules are being applied to a code block. – Waylan Apr 13 '20 at 02:07