Django, Pygments, Templates, Code Sharing, and Design

Welcome to the latest update!

I spent a total of about an hour on the “Social Code Sharing” application in the 2nd edition of “Practical Django Projects”, and I’m not completely finished with it, but I’ve got syntax highlighting and the basics covered. I can add, edit, and delete snippets, list snippets, and show a particular snippet, complete with syntax highlighting. In an hour. That’s pretty ok, considering I spent a lot of that time debugging what I would call, at best, an unexplained inconsistency in the book that caused me to run into a series of errors before finally figuring out the right way to do it (it’ll all be in the book review – stay tuned for that).

I don’t have links or user contribution set up yet. I only have a quick example up right now, which you can see here, which brings me to the design question: I want my navigation sidebar on the right, but I really don’t want the code to overlap it in any way. I’m kinda wondering if there’s an elegant way to fix that. I considered moving the sidebar to the left, but didn’t want to do that. I considered just making the main content area bigger, but then I’m just guessing, and praying that it fixes the problem for all future code snippets. What’s there now is just a CSS-based solution that creates a scrollable area for the code if it’s too long. Maybe this will suffice (though I have some CSSing to do to refine what’s currently there — the entire content area scrolls right now!)

Since there’s no example template for dealing with code highlighting in the book, and the downloadable code only goes through the first app in the book (the CMS app), here’s the template I’m using for the snippet_detail.hml file:

{% block title %}{{block.super}} | Random hacks{% endblock %}
{% block extrahead %}
<link rel="stylesheet" type="text/css" href="/static_media/llo_main/css/pygments.css" />
{% endblock %}
{% block content %}

 <ul>
 <li>{{ object.title }}</li>
 <li>Published: {{ object.pub_date }} Updated: {{ object.updated_date }}</li>
 <li>Language: {{ object.language }}</li>
 <li>Author: {{ object.author }}</li>
{% load markup %}
 <li>Description: {{ object.description_html|markdown }}</li>
 </ul>

<p>
{{ object.highlighted_code|markdown }}
{% endblock %}

Your CSS path will be different, in all likelihood, and there are some touches missing, like use of a variable to make the title bar dynamic and stuff, but right now I’m shooting for function — the form will come later.

For the snippet_list.html file, I found that what’s in the book just doesn’t work at all. It uses pagination using Django’s built-in pagination capabilities, but the small subset of a template that’s provided references a {{ page }} variable, which does nothing. The Paginator class appears to make individual pages available to templates in a variable you’d reference as {{ page_obj }}, not {{ page }}. Referencing {{ page_obj }} by itself (without referencing any attribute of it) results in output that says something like “<Page 1 of 1>”.

It’s not necessarily pretty to have those “< >” around the edges of the output, and it’s not necessary to use this method of getting the page number and the page count. The page number is available as an attribute of the page class, and the total number of pages is available from the associated paginator object’s ‘num_pages’ method, which you can grab via {{ page_obj.paginator.num_pages }}. You can see my snippets_list.html output here, and here’s my template (at time of writing – note that my site is a work in progress and can change without warning):

{% block content %}

<p>Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}</p>
<p>
{% if page_obj.has_previous %}
<a href="?page={{page_obj.previous_page_number}}">Previous page</a>
{% endif %}
{% if page_obj.has_next_page %}
<a href="?page={{ page_obj.next_page_number }}">Next page</a>
{% endif %}</p>

{% for snippet in object_list %}
 <ul>
 <li><a href="{{snippet.get_absolute_url}}">Title: {{ snippet.title }}</a></li>
 <li>Published: {{ snippet.pub_date }} Updated: {{ snippet.updated_date }}</li>
 <li>Language: {{ snippet.language }}</li>
 <li>Author: {{ snippet.author }}</li>
 <li>Description: {{ snippet.description_html }}</li>
 </ul>
{% endfor %}

{% endblock %}

In the interest of full disclosure, I should also say that, at time of writing, I haven’t added enough snippets to fully test the previous and next page links. I’ll get there, I’m sure — especially when I get user contributions in place, which will happen when I feel a little more confident that this is going to happen in a secure manner. Having been to PHP land, it’s a little unnatural for me to trust the code that comes with a framework to do things properly, which my sysadmin brain always parses as “securely, and in a functionally correct manner”.

Please share tips in the comments! That’s the update for now — stay tuned for more as the recreation of LinuxLaboratory.org continues to unfold.

  • Niki

    this example http://linuxlaboratory.org/snippets/1/ looks bad. Huge empty area on the right and code with scrollbar. New monitors are 16:9 and thin design does not fit.

  • m0j0

    So…. I should only design for new, 16:9 monitors?
    Don’t get me wrong, it’s nice to get some form of criticism, because I’m not a designer (I’m whatever the opposite of designer is), but how about an example of a site that’s doing this “properly” from a design perspective instead of just basically saying “this sucks”? Also, I say right in the article that I’m using a scrollbar and that I have toyed with a couple of other ideas. I’m looking for elegant alternatives. I guess if all you have to say is “this looks bad”, you’re not a good source of elegant alternatives.

    This morning, I actually looked around and found one site where code sharing is pretty much all they do, and guess what? THEY USE A SCROLLBAR!

  • Pingback: Django, Pygments, Templates, Code Sharing, and Design | Musings of … MoinMoin Wiki