<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>python &amp;mdash; Ignored By Dinosaurs 🦕</title>
    <link>https://www.ignoredbydinosaurs.com/tag:python</link>
    <description></description>
    <pubDate>Thu, 30 Apr 2026 13:01:28 -0400</pubDate>
    <item>
      <title>Easy markdown and syntax highlighting in Django</title>
      <link>https://www.ignoredbydinosaurs.com/275-easy-markdown-and-syntax-highlighting-django</link>
      <description>&lt;![CDATA[Hi there, I&#39;m new to Django. I love the contributed ecosystem, but all of the options that I found there for dealing with Markdown were just too heavy. I didn&#39;t need a Wysiwyg editor, I just wanted an output filter. As it turns out this is exceptionally easy to do!&#xA;&#xA;---&#xA;&#xA;Python has a really amazing lib situation, so I just found the smallest python Markdown lib that I could, it&#39;s called &#34;mistune&#34;. Do a pip install mistune.&#xA;&#xA;So within your app, let&#39;s call it &#34;blog&#34;, create a directory called templatetags. By the way, this is all pretty easy to parse out of their killer documentation. Create a file in there called markdownify.py. &#xA;&#xA;~python&#xA; # blog/templatetags/markdownify.py&#xA;from django import template&#xA;import mistune&#xA; &#xA;register = template.library()&#xA; &#xA;@register.filter&#xA;def markdown(value):&#xA;&#x9;markdown = mistune.Markdown()&#xA;&#x9;return markdown(value)&#xA;&#xA;~&#xA;&#xA;It is as simple as that. In whatever template you&#39;ll actually want to be rendering markdown, you&#39;ll need to include this templatetag with &#xA;&#xA;~python&#xA; {% load markdownify %}&#xA;~&#xA;&#xA;at the top of the template. Then you&#39;ll just pipe the output that you want to render like you do in every other template lib ---&#xA;&#xA;~html&#xA;{{ post.body | markdown | safe }}&#xA;~&#xA;&#xA;The full example of the template that renders this page is here.&#xA;&#xA;---&#xA;&#xA;But wait, there&#39;s more!&#xA;&#xA;How about syntax highlighting? We&#39;re programmers after all, and Python just happens to have the great-granddaddy of all syntax highlighting libs in Pygments. I&#39;ve known of Pygments for years, since it used to be a requirement of one of the Ruby libs to Markdown rendering (if you wanted synta highlighting). In other words, even Ruby leaned on Pygments for a great number of years.&#xA;&#xA;So pip install pygments. Then scroll down the page on the Mistune docs and follow along. You&#39;ll be adding some code to the markdownify.py file.&#xA;&#xA;~python&#xA;from django import template&#xA;import mistune&#xA;from pygments import highlight&#xA;from pygments.lexers import getlexerbyname&#xA;from pygments.formatters import HtmlFormatter&#xA;&#xA;register = template.Library()&#xA;&#xA;class HighlightRenderer(mistune.Renderer):&#xA;    def blockcode(self, code, lang):&#xA;        if not lang:&#xA;            return f&#34;&#34;&#34;&#xA;{mistune.escape(code)}&#xA;            &#34;&#34;&#34;&#xA;        lexer = getlexerbyname(lang, stripall=True)&#xA;        formatter = HtmlFormatter()&#xA;        return highlight(code, lexer, formatter)&#xA;&#xA;@register.filter&#xA;def markdown(value):&#xA;    renderer = HighlightRenderer()&#xA;    markdown = mistune.Markdown(renderer=renderer)&#xA;    return markdown(value)&#xA;~&#xA;&#xA;That HighlightRenderer class is directly out of the Mistune docs, so thank you Mistune Author! That is seriously all it takes, but you&#39;ll need a stylesheet, of which there are plenty. I searched for &#34;pygments stylesheets&#34; and came across this project, so you&#39;ll need to pick one of those themes and get it into your project somewhere. By default, the zenburn theme is expecting the wrapper div to have a CSS class of &#39;codehilite&#39; instead of what it needs - &#39;highlight&#39;, so a quick search and replace and I had syntax highlighting in less than 5 minutes.&#xA;&#xA;---&#xA;&#xA;\edit Sept 2016\&#xA;&#xA;So once you manage your way through all this, you&#39;ll be able to use &#34;fenced code blocks&#34; in your posts. They look like this --&#xA;&#xA;~&#xA;&lt;?php &#xA;&#xA;function foo() {&#xA; /// ...&#xA;}&#xA;~&#xA;&#xA;becomes&#xA;&#xA;&lt;?php &#xA;&#xA;function foo() {&#xA; /// ...&#xA;}&#xA;&#xA;You can use either a trio of tildes ~ or backticks \` to open and close one of those code blocks, and I typically just pass the file extension and it generally works. You can also write out the full name of the language.&#xA;&#xA;~&#xA;def method():&#xA;    return &#34;foo&#34;&#xA;~&#xA;&#xA;becomes&#xA;&#xA;def method():&#xA;    return &#34;foo&#34;&#xA;&#xA;Just be advised that it is possible to fatally hose your website if you happen to pass a language for which Pygments doesn&#39;t have a &#34;lexer&#34;, meaning that it has no idea how to highlight the syntax of that language. That happened to me with some Varnish config files that I tried to highlight with a .vcl extension on them. I don&#39;t remember how I fixed it but I&#39;m pretty sure it required going directly to the database to change the post since my site was toast. You are warned.&#xA;&#xA;#python #django]]&gt;</description>
      <content:encoded><![CDATA[<p>Hi there, I&#39;m new to Django. I love the contributed ecosystem, but all of the options that I found there for dealing with Markdown were just too heavy. I didn&#39;t need a Wysiwyg editor, I just wanted an output filter. As it turns out this is exceptionally easy to do!</p>

<hr>

<p>Python has a really amazing lib situation, so I just found the smallest python Markdown lib that I could, it&#39;s called <a href="https://mistune.readthedocs.org/en/latest/">“mistune”</a>. Do a <code>pip install mistune</code>.</p>

<p>So within your app, let&#39;s call it “blog”, create a directory called <code>templatetags</code>. By the way, this is all pretty easy to parse out of <a href="https://docs.djangoproject.com/en/1.9/howto/custom-template-tags/">their killer documentation</a>. Create a file in there called <code>markdownify.py</code>.</p>

<pre><code class="language-python"> # blog/templatetags/markdownify.py
from django import template
import mistune
 
register = template.library()
 
@register.filter
def markdown(value):
	markdown = mistune.Markdown()
	return markdown(value)

</code></pre>

<p>It is as simple as that. In whatever template you&#39;ll actually want to be rendering markdown, you&#39;ll need to include this templatetag with</p>

<pre><code class="language-python"> {% load markdownify %}
</code></pre>

<p>at the top of the template. Then you&#39;ll just pipe the output that you want to render like you do in every other template lib —-</p>

<pre><code class="language-html">{{ post.body | markdown | safe }}
</code></pre>

<p>The full example of <a href="https://github.com/JGrubb/django-blog/blob/master/blog/templates/blog/post_detail.html">the template that renders this page</a> is here.</p>

<hr>

<h3 id="but-wait-there-s-more">But wait, there&#39;s more!</h3>

<p>How about syntax highlighting? We&#39;re programmers after all, and Python just happens to have the great-granddaddy of all syntax highlighting libs in <a href="http://pygments.org/">Pygments</a>. I&#39;ve known of Pygments for years, since it used to be a requirement of one of the Ruby libs to Markdown rendering (if you wanted synta highlighting). In other words, even Ruby leaned on Pygments for a great number of years.</p>

<p>So <code>pip install pygments</code>. Then scroll down the page on the Mistune docs and follow along. You&#39;ll be adding some code to the <code>markdownify.py</code> file.</p>

<pre><code class="language-python">from django import template
import mistune
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import HtmlFormatter

register = template.Library()

class HighlightRenderer(mistune.Renderer):
    def block_code(self, code, lang):
        if not lang:
            return f&#34;&#34;&#34;
```
{mistune.escape(code)}
```
            &#34;&#34;&#34;
        lexer = get_lexer_by_name(lang, stripall=True)
        formatter = HtmlFormatter()
        return highlight(code, lexer, formatter)

@register.filter
def markdown(value):
    renderer = HighlightRenderer()
    markdown = mistune.Markdown(renderer=renderer)
    return markdown(value)
</code></pre>

<p>That <code>HighlightRenderer</code> class is directly out of the Mistune docs, so thank you Mistune Author! That is seriously all it takes, but you&#39;ll need a stylesheet, of which there are plenty. I searched for “pygments stylesheets” and came across <a href="https://github.com/richleland/pygments-css">this project</a>, so you&#39;ll need to pick one of those themes and get it into your project somewhere. By default, the zenburn theme is expecting the wrapper div to have a CSS class of &#39;codehilite&#39; instead of what it needs – &#39;highlight&#39;, so a quick search and replace and I had syntax highlighting in less than 5 minutes.</p>

<hr>

<p>*edit Sept 2016*</p>

<p>So once you manage your way through all this, you&#39;ll be able to use “<a href="https://help.github.com/articles/creating-and-highlighting-code-blocks/">fenced code blocks</a>” in your posts. They look like this —</p>

<pre><code>```php
&lt;?php 

function foo() {
 /// ...
}
```
</code></pre>

<p>becomes</p>

<pre><code class="language-php">&lt;?php 

function foo() {
 /// ...
}
</code></pre>

<p>You can use either a trio of tildes <code>~</code> or backticks ` to open and close one of those code blocks, and I typically just pass the file extension and it generally works. You can also write out the full name of the language.</p>

<pre><code>```py
def method():
    return &#34;foo&#34;
```
</code></pre>

<p>becomes</p>

<pre><code class="language-python">def method():
    return &#34;foo&#34;
</code></pre>

<p>Just be advised that it is possible to fatally hose your website if you happen to pass a language for which Pygments doesn&#39;t have a “lexer”, meaning that it has no idea how to highlight the syntax of that language. That happened to me with some Varnish config files that I tried to highlight with a <code>.vcl</code> extension on them. I don&#39;t remember how I fixed it but I&#39;m pretty sure it required going directly to the database to change the post since my site was toast. You are warned.</p>

<p><a href="https://www.ignoredbydinosaurs.com/tag:python" class="hashtag"><span>#</span><span class="p-category">python</span></a> <a href="https://www.ignoredbydinosaurs.com/tag:django" class="hashtag"><span>#</span><span class="p-category">django</span></a></p>
]]></content:encoded>
      <guid>https://www.ignoredbydinosaurs.com/275-easy-markdown-and-syntax-highlighting-django</guid>
      <pubDate>Wed, 23 Mar 2016 00:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Goodbye Rails, Hello Django</title>
      <link>https://www.ignoredbydinosaurs.com/272-goodbye-rails-hello-django</link>
      <description>&lt;![CDATA[So here it is. The last version of this blog - a Rails frontend to a Postgres backend - actually stood for almost 2 and a half years. I think that&#39;s probably a record. &#xA;&#xA;In keeping with my decided new theme for this blog however, I&#39;ve decided to rewrite the thing in Django. Not that you can&#39;t google it yourself, but Django is (at a high level) basically the Python version of Rails. Actually, it&#39;s basically the Python version of every MVC web framework. It&#39;s been around for 10 years, so it is far from the hot-new-thing. I&#39;ve finally been doing this for long enough that I shy away from the hot-new-thing and actively seek out boring, tested solutions to problems. &#xA;&#xA;At work we&#39;ve begun a small project that we were targeting to build on Drupal 8. Faced with the timeframe, the relative lack of basic modules for building Drupal 8 sites, and the learning curve for the code that we&#39;d inevitably have to write on our own I pitched the idea to my team to try something completely different. I prefaced it with &#34;this is a terrible idea, so raise your hand at any point&#34;, but surprisingly they were all amenable. We all spent a day going through the amazing tutorial and the amazing documentation and they were still on board. So I decided to rebuild this blog to take the training wheels off and give us all some reference code for some of the simple features that weren&#39;t walked through in the tutorial - taxonomy, sitemaps, extending templates, etc.&#xA;&#xA;Amazingly it took me all of 4 hours to rebuild the whole thing and migrate the data from one PG schema into the one that Django wants to use. Django is even easier to use than Rails - a fact that blew my mind once I started playing with it. &#xA;&#xA;The deployment story however, is a shit show. I spent as many days trying to get this thing up on a Digital Ocean server as I spent hours building the application in the first place. I&#39;m hoping to find that there is an easier, more modern means for serving Python apps in 2016 after some more digging. &#xA;&#xA;Anyway, thanks for stopping by!&#xA;&#xA;#generaldevelopment #python #django]]&gt;</description>
      <content:encoded><![CDATA[<p>So here it is. The last version of this blog – a Rails frontend to a Postgres backend – actually stood for almost 2 and a half years. I think that&#39;s probably a record.</p>

<p>In keeping with my decided new theme for this blog however, I&#39;ve decided to rewrite the thing in Django. Not that you can&#39;t google it yourself, but Django is (at a high level) basically the Python version of Rails. Actually, it&#39;s basically the Python version of every MVC web framework. It&#39;s been around for 10 years, so it is far from the hot-new-thing. I&#39;ve finally been doing this for long enough that I shy away from the hot-new-thing and actively seek out boring, tested solutions to problems.</p>

<p>At work we&#39;ve begun a small project that we were targeting to build on Drupal 8. Faced with the timeframe, the relative lack of basic modules for building Drupal 8 sites, and the learning curve for the code that we&#39;d inevitably have to write on our own I pitched the idea to my team to try something completely different. I prefaced it with “this is a terrible idea, so raise your hand at any point”, but surprisingly they were all amenable. We all spent a day going through the amazing tutorial and the amazing documentation and they were still on board. So I decided to rebuild this blog to take the training wheels off and give us all some reference code for some of the simple features that weren&#39;t walked through in the tutorial – taxonomy, sitemaps, extending templates, etc.</p>

<p>Amazingly it took me all of 4 hours to rebuild the whole thing and migrate the data from one PG schema into the one that Django wants to use. Django is even easier to use than Rails – a fact that blew my mind once I started playing with it.</p>

<p>The deployment story however, is a shit show. I spent as many days trying to get this thing up on a Digital Ocean server as I spent hours building the application in the first place. I&#39;m hoping to find that there is an easier, more modern means for serving Python apps in 2016 after some more digging.</p>

<p>Anyway, thanks for stopping by!</p>

<p><a href="https://www.ignoredbydinosaurs.com/tag:generaldevelopment" class="hashtag"><span>#</span><span class="p-category">generaldevelopment</span></a> <a href="https://www.ignoredbydinosaurs.com/tag:python" class="hashtag"><span>#</span><span class="p-category">python</span></a> <a href="https://www.ignoredbydinosaurs.com/tag:django" class="hashtag"><span>#</span><span class="p-category">django</span></a></p>
]]></content:encoded>
      <guid>https://www.ignoredbydinosaurs.com/272-goodbye-rails-hello-django</guid>
      <pubDate>Sat, 19 Mar 2016 00:00:00 +0000</pubDate>
    </item>
  </channel>
</rss>