Today marked the last day of my internship at Eyespot. There was such an outpouring of good will that it made me want to quit school immediately and stay with Eyespot.
I could not have asked for a better experience!
That's all for today.
Very interesting discussion going on right now about Django's templating language and whether to split it off into its own separate library. One of the justifications is that it will "feel" easier to plug in other template languages into Django itself. Funny how I just blogged about how easy this is already.
Also, previously this site was run with apache2 and perlbal. Now it's running apache2 and nginx. At some point I'm going to make the switch to having all of the media pointing to an nginx-only server which short circuits the mod_python (also soon to be mod_wsgi, lol) handlers altogether.
Sorry that this is another in a line of short posts, but I expect this trend will continue as I move twice in the next 2 weeks. Crazy stuff happening in my life right now!
Sphinx Search ROCKS! I'm pretty sure it'll be the solution to my MusicBrainz problems for my secret project. I'm going to set up a simple postgres server holding the MusicBrainz database, with Sphinx Search installed, and have it index on a cron. It'll be awesome! After trying out Lucene and its derivatives and being so underwhelmed, it's exciting to discover an app that truly seems to rock. I'll report back on it later, but right now the indexer is 4 million queries into a 60 million query index. Yeah, it's going to be a while.
I've been wanting to test drive two new technologies this past week, the first is Blueprint, the CSS Framework which I saw on Digg a few days ago. I also really wanted to try some new stuff with FreeComments, including saving people's login information in the session. I'm messing with both of those things in a side-side project related to The Totally Rad Show which I think promises to be really fun. I've spent only a couple of hours on it, but I think it's going to be probably my first project that people end up using.
So, Stick Tuned for a fun announcement from me in the next week or 2 weeks at the latest. (The problem with this project is there's lots of data to enter which will take time.)
That's it for today, a short and sweet entry into this blog-o-rama.
Django is my preferred web development framework. As such, I like it as a total solution: ORM, Template System, and Request/Response Mechanisms. One of the criticisms that gets tossed around regarding Django is that it's a monolithic web framework, and as such it is not loosely coupled. I would argue that while it is a monolithic framework, it is still loosely coupled, and I'll prove it by showing just how easy it is to replace the templating system.
After a quick google search for django and cheetah, I was surprised to find that there seem to be no really great examples online of the replacement of the template part of the Django stack. That being the case, I have decided to provide some examples of how that can be accomplished. In short, I'm going to demonstrate how to use the Cheetah template language with the Django web framework.
Before we delve into how to integrate Cheetah with Django, first let's look at some basic Cheetah syntax. Basically all placeholders in cheetah templates are prefixed by $, and all control flow logic is prefaced by #. Beyond that, mostly the syntax follows normal Python syntax.
If there's a python object test = [1, 2, "3.1415", 4, range], the Cheetah placeholder $test[0] would return 1, $test[2] would return 3.1415, and $test[4](0,$test[1]) would return [0, 1]. To learn about control flow or any of the more advanced topics, you'll have to visit the excellent Cheetah Users Guide.
To demonstrate using Cheetah with Django, we're going to use the canonical example: the blog. First, the model (about the most simplistic one I could think of for a blog):
from django.db import models
class BlogPost(models.Model):
title = models.CharField(maxlength = 128)
body = models.TextField()
def __unicode__(self):
return self.title
Now, let's make sure to add a template folder to TEMPLATE_DIRS in settings.py:
TEMPLATE_DIRS = (
'/path/to/myproject/templates',
)
Now, one aspect of Django that I've gotten really accustomed to is the render_to_response method. It's nice to be able to specify a template name and pass in some context, and get an HttpResponse object back. So we'll start by replacing that method, but for cheetah:
import os.path
from Cheetah.Template import Template
from django.conf import settings
from django.http import HttpResponse
def render_to_response(template_name, context, **kwargs):
for template_dir in settings.TEMPLATE_DIRS:
path = os.path.join(template_dir, template_name)
if os.path.exists(path):
template = Template(file = path, searchList = (context,))
return HttpResponse(unicode(template), **kwargs)
raise ValueError, 'Could not find template for %s' % template_name
This code snippet can go anywhere, but to make it easy you can just put it in your views.py. As for how it works: basically we're just iterating over each template directory in TEMPLATE_DIRS. If we find that a file exists, we create a cheetah Template object with that file as its base and with the specified context as its search list. Then, we simply render the result into an HttpResponse object. I feel that this solution is both simple and robust--two concepts that usually exclude each other.
So, how would a simple view look using our new helper render_to_response?
from myproject.blog.models import BlogPost
def index(request):
blogs = BlogPost.objects.all()
context = { 'blogs' : blogs }
return render_to_response('index.tmpl', context)
Ok, it's going to take a bit of explaining for that last snippet. There's a lot of advanced things going on that make it look totally unfamiliar. But actually that's just one big lie: this looks EXACTLY like any other Django view! We've just completely and transparently replaced the templating system of Django, and all it took was a 7-line helper function. But we're not done yet. We still have to write the template:
<html>
<head><title>I can has cheetah templates!</title></head>
<body>
#for $post in $blogs
<div class="blogpost">
<h1>$post.title</h1>
<p>$post.body</p>
</div>
#end for
</body>
</html>
Now point a url to the example view, and watch the magic unfold. I'm not a Cheetah user normally, so I can't really comment about some of the more complex features of that language, but I can't imagine that enabling them would be much more difficult than what we've already done here. So, that means I'm totally aware that there may be some naivity in my implementation. If so, please comment and I'll change it accordingly.
django-simpleaggregation
I have just released Version 0.2 of django-simpleaggregation. Updates in this release:
- The detection of an update on a unique field was not being correctly computed. It used to use the addition of an id field to determine whether an aggregate should be incremented, but now it uses another hook into the dispatcher to annotate pre-save the model instance with some metadata related to aggregation.
- The old helper functions which were used to get aggregate data have now been replaced with an object which is smarter and cleaner. I suspect there will be a few more cleanup changes to the implementation of this, but the API should now stay fairly stable.
- Pagination is now usable. In 0.1, some rudimentary pagination abilities existed, but now it supports most of the same pagination data that a generic view gives a template.
Eflorenzano.com
I've updated this site to use freecomment and the excellent django-comment-utils by James Bennett, which allows me to automatically use Akismet to block spam. Hopefully this will solve the problems that I've been having with comment spam, despite the efforts that I've made in the past to combat it programmaticaly.
Eyespot
My internship at eyespot is coming to an end in a little over a week. It's really bittersweet for me: it has been such a great experience, moving out to California and working on the "Web too pwoint oahh" craziness, but I miss my friends from the midwest. I was a little nervous to take this internship, because of the technologies that I knew eyespot was using (notably, Perl), but my experience this summer only reinforces my original thought: programming language doesn't matter, it's people who matter.
If it's people who matter, eyespot matters a whole lot, because there has been no other time when I have respected the people around me even close to as much as I respect those at eyespot. I've never seen someone who can come up with the solution to a problem as I'm still trying to grasp the idea of the problem itself. I've never seen people so willing to listen to and implement the ideas of an intern. I've never seen a group of coworkers who were more welcoming and tight-knit, hanging out after work as much as during. And most of all, I've never seen a group of people who were more skilled at their craft, as the people at eyespot.
Sure, there are some things that I think could be done better at eyespot. Sometimes, frankly, I'm surprised that it all works. But I'm not going to go into those things, however, because it's actually not relevant to my point.
So, all said, I'm excited for what the future holds for me and eyespot, my working life after college, etc. But to bring it back to my earlier point, I'm also excited for my last year in college. Being away from home and family and friends has made me realize just how much I appreciate all of them on a daily basis, and perhaps just how much I take them for granted. I could care less about going back to learn computer science--I'm going back for the people (is this a recurring theme, or what?)
I'm going to carpe diem this next school year, because it's the last one I've got.
All Content

