Dec

23

Markdown w/ Pygments: Round 2

Dig back into my vast blog archive and you will find this post: I said it, I did it. Therein you will find my bumbling, ham-fisted solution for integrating pygment code highlighting into markdown.

I just wandered back past this code today and then stumbled across the actual right way to do this.

More...

Dec

23

What I did on the Monday before Christmas (yesterday)

My mom is in town. This is what she and I got up to yesterday:

More...

Dec

17

I know! I'll talk about video games!

I just listened to a short documentary on video games on the Search Engine podcast. It's by Jesse Brown, the host of the show, and it's a reflection on video games prompted by the recent death of a teen who ran away from home because his parents took away his XBox.

I really like this podcast, and I think Jesse Brown does a great job producing it. This documentary, however, was pretty bad. It was produced for one of CBC Radio's more mainstream shows and I felt that it pandered to the audience's sense of worry and fear about video game culture.

I wrote two comments on the Search Engine blog. Here they are.

More...

Dec

14

Run Sam Run (Attempt 2)

My roommate A is athletic. I, on the other hand follow the usual fitness habits of a programmer. For the past two Saturdays I have tried joining A when he goes on his 6 mile run. I'm falling a little short of six miles. But that's ok. I expected that. I made it a little further yesterday than I did last week. If I can get a little further each week I'll be happy.

Here's the nerd angle: I used my account on mapmyride to log my run. If I can manage to abuse my legs and lungs every week I should be able to come back and play with the fun Google Maps doodad.

Anyway, here's the doodad:

More...

Dec

11

On PIL and aggdraw

This isn't in "Developer Stuff" because it isn't related to Django and I don't want to pollute the Django Community Aggregator.

Along with my addition of the "public" field last night, I also refactored my clock rendering code to use the aggdraw library because it's compatible with PIL and it renders nice, anti-aliased lines.

The refactoring wasn't completely trivial, but it wasn't so bad, but I ran into a whole other mess when I tried compiling aggdraw on my slice.

More...

Dec

11

Testy

Anyone attempting to dip into my modest archive this morning would have seen an error message instead.

I discovered a bug in how my archive_month view was working and I fixed it. And in the process I opened a much worse bug. This is one of the classic narratives, along with "boy meets girl", "stranger comes to town" and the rest.

Let me tell you all about it...

More...

Dec

11

Private Posts and Custom Managers

I have all these cool ideas for how this blog is going to knock the socks off of sliced bread, or at least, all things since sliced bread. But to get there, I keep stumbling over all this pesky functionality I don't have.

In a way it's one big lesson in project management. All the little, round-down-to-zero-time tasks add up to an alarmingly non-zero number.

Today's addition is a public checkbox on the BlogPost object. That, plus the custom manager that goes with it. Plus the updates to the views. Plus the test to make sure it works. Plus the Django Evolution code.

Read on for more! I've got some racy opinions on custom managers in here that you won't want to miss!

More...

Dec

9

Cue The Sun

This is my post for showing off how the sun gets rendered during evening twilight. I am tweaking the publish date a bit because I -ahem- forgot to post this a little earlier.

Dec

9

Hickory Dickory Dock...

This is the nerdiest, least useful thing I've added to this site so far: an analog clock renderer!

Check it out: you get a regular clock with an hour hand and a minute hand, but you also get a sun indicator, to help you tell AM from PM. When it's daylight, the sun travels through the sky in nice happy yellow. When it's night time the sun travels around the lower half of the circle and gets drawn a dark blue. The extra fun part is that if it's near sunrise or sunset, the sun's colour is drawn from a gradient between the noon-day yellow and a bright red. I'll have to make a point of posting at dusk tomorrow.

I have no idea if this technique for representing time is at all intuitive, but I really enjoyed making it.

More...

Dec

8

Free Previews

My friends, I have something exciting (and completely unnecessary) in the works.

To pave the way for all the stuff I want to say about that, I've added previewing to my blog.

Let me tell you all about it, below the fold.

More...

Dec

7

Darwin Rears His Head

I'm using Django Evolution with this project because I knew I would need to muck with my models at some point. Ladies and gentlemen, that point has come!

In order to get categories set up I had to add a foreign key to the Category model from my BlogPost model. I've used the "./manage.py --hint" → "./manage.py --hint --execute" pattern before in other projects, but I decided to use Django Evolution's "Stored Evolutions" feature this time. It turned out to be painless, and I think i could smell rose petals and the absence of stress.

  • I ran ./manage.py --hint

  • I copied the lines between the "---------" bits into a file inside blog/evolutions. That looks like this:

from django_evolution.mutations import *
from django.db import models
 
MUTATIONS = [
AddField('BlogPost', 'category', models.ForeignKey, null=True, related_model='blog.Category')
]

I also created a __init__.py file in there.

  • I added this line to the __init__ file:

SEQUENCE = ['add_category_fk']

  • I got all my changes checked in, pushed the code up to my slice and ran ./manage.py evolve.
    Django Evolution found the evolution file, warned me that it might destroy my data or blot out the sun if I let it run, and then executed the evolution perfectly.

This is a simple case, I know, but this was still a lot easier than firing up psql. A tool that only helps with the easy 80% of the cases is still a useful tool, I think.

Dec

7

Category: Not Dead

Good evening, world!

I have been wracked by horrible guilt this past week, knowing that my new, youthful blog was lying fallow.

Here I am, making amends!

I've added categories to my blog. I now have the ability to separate my developer nonsense from my "personal" nonsense. (Note: "Personal" here is used not to mean "private" but rather, "less interesting to others".) I've also added category-based news feeds. Just go to the category page and subscribe to the feed from there.

Adding categories required new code in a bunch of places. It's not all very interesting. I split my blog post list displaying template code out into a sub-template called "_blogpost_list.html", because I'm using it in a few different templates now, but the code's basically the same.

I did create two new template tags. One is the archive nav code I had earlier, refactored:

@register.inclusion_tag('blog/_archive_nav.html')
def archive_nav(month=None, category=None):
queryset = BlogPost.objects.all()
if category:
queryset = queryset.filter(category=category)
return {'category': category,
'active_month': month,
'month_list': queryset.dates('pub_date', 'month')[::-1]
}

With the new archive nav code, I'm giving up on using the date_list object that the date-based generic views provide. date_list only lists the years that contain content. I was using a little template filter that would take a date representing a year, and return a list of all months with content in that year. It worked great when I always wanted to examine all the content, but it became a nuisance when I sometimes wanted to restrict it to only those blog posts that were in a certain category. I could have fiddled some more with the filter but I decided it would be tidier to write a complete template tag instead and leave date_list behind.

Here's the template:

<ul class="nav-bar">
<li>Archive: </li>
{% for month_date in month_list %}
<li{% ifequal month_date.date active_month %} class="active"{% endifequal %}>
{% with month_date|date:"F" as month_str %}
{% if category %}
<a href="{% url category_archive_month category_slug=category.slug,year=month_date.year,month=month_str.lower %}">
{{ month_str }} {{ month_date.year }}
</a>
{% else %}
<a href="{% url blog_archive_month year=month_date.year,month=month_str.lower %}">
{{ month_str }} {{ month_date.year }}
</a>
{% endif %}
{% endwith %}
</li>
{% endfor %}
</ul>

I discovered something new when I was updating my other templates to use archive_nav properly: Django templates don't support the "None" keyword. When I'm loading the archive nav inside the category detail page I need to pass the category, but I don't have an active month to pass. Here's what I settled on:

{% archive_nav "" category %}

It seems like there ought to be a nicer way to do this, but keyword arguments don't work with simple or inclusion tags and I can't use None.

Anyway, at the end of the day, we're left with an exciting new feature that every other blog already had without even thinking about it. I've got some great ideas on rotating, circular vehicle conveyance tools, as well.