Google tries to get smart

Thinking about Jon Udell having a higher Google ranking than Jon Stewart (which I just helped) I checked how Andy is doing these days. Sadly I don't figure at all in the ranking for Andy, I think a few years ago I got on the front page.

But I've always been able to hold down Andy McKay top spot. Although there's some good prof's out there giving me good battering. But now I'm being beaten by Andy MacKay, because Google is being smart and inserting an extra a in there.

He's a worthy winner and it's going to take a bit to knock him off. But now I have to compete against McKay and MacKay's hey that's not fair. Fortunately it doesn't really matter that much :).

Django Tutorial for Page Templates (Part 1)

This tutorial is a re-writing of the Django Tutorial in the documentation on the Django website. In this I step through the same tutorial covering the templating sections, but focusing on how they would look using Page Templates instead of the Django templating language.

The demo code and so on is from that site and all credit to the authors of that tutorial. As ever all mistakes are mine.

To run the code in this demo, you'll need Simple TAL and Simple Template. Check out Simple Template from here and follow the readme contained within that directory:

svn co http://svn.clearwind.ca/public/django/simpletemplate

If you don't fancy typing everything in, then please checkout code used in these examples from:

svn co http://svn.clearwind.ca/public/django/polltutorial

Already to go. Then start following through the tutorial and through parts one and two. Neither of these touch on templating at all so nothing relevant to us there. Tutorial three is where the fun starts to happen, in the section Write views that actually do something.

Simple template provides key api calls for rendering templates, that you can use instead of the builtin ones. Instead of:

from django.template import Context, loader

Use:

from django.contrib.simpletemplate.public import get_template

Instead of the given example, use:

from django.contrib.simpletemplate.public import get_template
from django.template import Context
from mysite.polls.models import Poll
from django.http import HttpResponse

def index(request):
    latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
    t = get_template('polls/index.pt')
    c = Context({
        'latest_poll_list': latest_poll_list,
    })
    return HttpResponse(t.render(c))

The key changes here are line 1, with that different import. Also on line 8 we are no longer using index.html, we are using a Page Template which follows a convention established from Zope of .pt as extension so we'll call ours index.pt.

The index.pt looks like the following:

<tal:block tal:condition="latest_poll_list">
    <ul>
        <li tal:repeat="poll latest_poll_list"
               tal:content="poll/question">question</li>
    </ul>
</tal:block>
<tal:block tal:condition="not: latest_poll_list">
    <p>No polls are available.</p>
</tal:block>

If you are familiar with TAL then this will hopefully make sense. The next step covers using "A shortcut: get_object_or_404()", this is relatively straightforward, to use the render_to_response replace the current import with the following:

from django.contrib.simpletemplate.public import render_to_response

Just remember to point to a .pt template, not a .html one.

And finally in tutorial three there is one more example that covers the detail view. Here's how detail.pt looks in Page Templates:

<h1 tal:content="poll/question">Poll Question</h1>
<pre>
<p tal:condition="error_message|nothing">
    <strong tal:content="error_message">Error</strong>
</p>

<form action="" 
         tal:attributes="action string:/polls/${poll/id}/vote/" 
         method="post">
    <tal:block tal:repeat="choice poll/choice_set/all">
        <input type="radio" name="choice" 
                tal:attributes="for string:choice${choice/index};
                value choice/id" />
        <label tal:attributes="for string:choice${choice/index}"
                tal:content="choice/choice">The choice<label>

And that's it, on to tutorial four in another day.

Pledge to buy hand made

Following on from my Christmas Manifesto a Pledge to buy hand made this year. Danae just spent a few days making toys for one of our daughters friends birthday, doing it in bulk, I think a few people will get them this year :)

When to rewrite

I've got a bug in my Rails application, well actually a few of them. It allows you to browse and administer users in an LDAP tree. Yes, the first time I was confronted with this, I asked "hasn't this been done already?" The answer was: "not well". So it was written as a Rails app. A while back I had to trip through this application and it was hell.

We put this application onto another site at Blue Fountain and sure enough it failed. It's not doing the job. So on my commute I rationalised why I'm going to throw that Rails away and start again. Here's my list:

  • Was the developer so damn clever doing X, Y and Z that he forgot some mortal might have to maintain it? Does the person now maintaining not have super ninja Widget Fromboid foo? Was there any code documentation or comments? Was this just a developer getting high off being so damn clever?
  • Is it reusable? Are you going to get rich off maintaining this thing? Is it really just going to start dragging you down time and time again? Is this write once and maintain until you can run screaming away from the compamy?
  • Does it have automated tests of any kind? Unit tests, integration tests, browser tests anything, this is the 21st century right?
  • How many bugs has it had, has it got some now, are those bugs hard to solve than the Middle East peace process? You can tell the death march of a project when banging noises are made on developer's desks and the walk round with a dull glaze and red mark on their forehead.
  • Really how hard would this to be replace? Remember everything is a) easier the second time and b) way harder because of all the undocumented wierd edge cases. Every developer will tell you a) and every project manager will roll his eyes and say b). The answer is really c). I'm not sure where that is but you'll find out.

In this case:

  • I've tried and when you start messing in the Active Record internals you know something is wrong.
  • Nope, we've seen this already. Further the UI is tied into the back end nice and tight. This is actually a useful library.
  • Yes it does, but they don't work.
  • Lots and still hasn't got created confidence, having problems with scaling and leaving file descriptors open all over the place.
  • Not hard, honest no edge cases. All the edge cases work around LDAP or Active Record.

So tommorrow its moving to Django. I reserve the right to amend this blog post to change all the above to justify this change.

Old Doctor Who

Danae has seen all the new Doctor Who's but never seen the old one's so my references to Daleks, Cybermen, long scarves and jelly beans sometimes go past her. So we started getting some of the old ones.

We watched the Hand of Fear the other night. But I just love the ending. So there is being from 150 million years ago, silicon (not carbon) based. Absorbs radiation, can read peoples minds, absolute genius. Regenerates itself inside a nuclear reactor and takes over people's minds and controls them. A nuclear missile attack, no problem, gets absorbed. Doddle.

How does the doctor defeat the being. By hiding behind a rock and shouting pull to his assistant on the other side of the corridor. This almost omnipotent being then trips and falls into a seemingly bottomless abyss. Brilliant, the universe's greatest peril defeated by a scarf.

Macbook battery

Third time back in to the Apple store with my macbook, this time to get the battery which died whilst in Italy. We left it in hibernate mode in the UK and it discharged completely, so much it won't start up again. This is covered in the 2 year battery warranty.

I'm always impressed by the help at an Apple store once I've actually been helped. To see someone you have to get an appointment. I've tried 4 times and found those appointments completely impossible for my times. Further the Apple store is a 1.5 hour drive into Manchester, a terrible and unpredictable place to drive to, expect long queues.

So my new habit is to set an appointment, get there when I do and then stand and wait and wait and wait. Typically there will be about 8 free people in the store. None will talk to me or even acknowledge I might need help. Finally I'll get a break with a Genius and talk to them. This problem which I'd researched ahead of time was fixed in 5 minutes and out the door.

This policy sucks completely. Reserving time is fine, but ensure 50% of the time is not reserved and actually service people when they need help. Rant over. I think everything that can be replaced under warranty has been so until their ultra light small macbook comes out, I won't be back for a while.

Rails to Django

Yesterday saw the beginning of the end of our Rails applications as we started moving them over to Django. A simple one was our timesheet application (yes we have one internally) that was in Rails.

The rails application was around 1000+ lines of code (just in the app directory) of which I imagine a lot was the boiler plate scaffold. It used a plugin we developed called Toffee which did the user interface and then one for pretty user interface. It had quite a few bugs, took 2 days to write (which I still find hard to believe).

The django application (with the following exception) took 1 hour to write and had about 80+ lines of code (mostly because I write with lost of new lines). No bugs so far. The tricky bit that took me 2 hours is a) changing django to trust REMOTE_USER sent from our Apache which does LDAP auth and b) figuring out how to set this user on the timesheet model. I'm still not happy with the solution to the latter and need to research, I think it should be a manipulator so the admin interface uses that.

Today we worked on moving an old Zope application to Django, looking good so far.

Thunderbird

With all the news about David Ascher and Thunderbird, I switched back to Thunderbird the other day. But a day of it and I switched back to OS X's Mail.app. In essence there was nothing that it gave me over Mail.app, or nothing I could spot.

  • After being used to the Mac I found the large number of preference screens all over the place confusing, took me a while to find anything. I remember neons ago Thunderbird was far more polished than Outlook Express. Now it feels out of date.
  • Most of the extensions weren't that useful, extensions are Thunderbird's weapon and they were hard to do much useful.
  • I got a large number of spinning Mac discs of hell, due to I believe SSL incompatabilities with my server. I did later find an extension to solve this, that didn't work.
  • The RSS feed was nice and I do like that reader, but realised that I like reading that in a browser anyway.
  • The LDAP lookup of my address book did work well and was nice. But Mail.app does that and feels more polished to me.

Saying all this, Thunderbird is still the best non-Mac client there is and I look forward to what the new changes will bring. Except maybe for gmail. Or mutt.

Moodle technical choices

Had the pleasure of meeting Martin Dougiamas the other day. A thoroughly nice chap and had a brief chat with Martin about Moodle. I confessed I had problems with Moodle, being used to an object model like Zope. A few interesting things:

  • Many years ago Martin tried his first prototype in Zope, he likes Python and thought it would be a good fit. He got ZODB corruptions (this was about 2001-2) and gave up on the ZODB and Zope.
  • Having it in PHP makes it very easy and accesible for new users.
  • By not needing root access Moodle has been installed on lots of hosts and often cheap hosts with little hassle.

All good points and certainly Moodle is a roaring success.