Django “lorem ipsum” generator (and a new contrib.webdesign module)
The Django Web Framework project just added a new contrib.webdesign module with an amazingly simple, but incredibly handy first feature: a lorem ipsum generator. The idea is that a project’s base templates can include generated lorem ipsum for testing layout and page flow, but inheriting templates can override the generated text once real content is available.
The lorem tag is used like this (via the contrib.webdesign docs):
In practice, you might do this:
templates/template.html:
<html>
<head>
<title>{% block article_title %}{% lorem 5 w %}{% endblock %}</title>
</head>
<body>
<div class="article">
<div class="article_title">{% block article_title %}{% lorem 5 w %}{% endblock %}</div>
<div class="article_body">{% block article_body %}{% lorem 4 p %}{% endblock %}</div>
</div>
</body>
</html>
And then inherit when you’re ready:
templates/article.html:
{% extends "template.html" %}
{% if article %}
{% block article_title %}{{ article.title }}{% endblock %}
{% block article_body %}{{ article.body }}{% endblock %}
{% endif %}
Previously, I used to just paste lorem ipsum text directly into the main template (wrapped in block tags for overridding), but this new tag will let you skip the copy/paste routine. Very nice!
“Web Typography Sucks“, the SXSWi 2007 presentation (w/notes.) Also see: http://webtypography.net/sxsw2007/.
My previous post, “Passing JSON via the X-JSON HTTP header with Django and Prototype“, contained an example on writing custom HTTP headers from a Django-based web application. Continuing with that theme, here’s another header trick that I use in one of my apps to force the browser’s “Save As…” dialog box when viewing a particular URL.
The feature that I wanted was the ability to generate an XML file based on an HTTP GET request, but to have the browser open a “Save As…” dialog instead of attempting to render it (as would normally happen with XML in a modern browser.) The solution is to exploit the web browser behavior of not handling unknown mime types. A sample implementation (written in Python for the Django Web Framework) follows:
def save_as_xml(request):
import datetime
current_time = datetime.now()
response = HttpResponse('PUT THE XML HERE')
response['Content-Type'] = 'application/x-generated-xml-backup'
response['Content-disposition'] = 'Attachment; filename=export.%s.xml' % (current_time.strftime("%Y-%m-%d"))
return response
Setting the Content-Type header to a made-up type ensures that the browser will not attempt to render the file. The Content-disposition header provides the mechanism for suggesting the filename of the content to be saved on the viewer’s system. In this case, I’m using the standard `datetime` module to insert the date into the suggested filename.
One of the demo sites I was working on this week needed to pass a small amount of JSON back with it’s page results. There are a few ways to do this (and I’d suggest this post, “Loading Content with JSON” as a starting point if you’re looking for ideas), but for simplicity, I decided to take advantage of the automatic X-JSON HTTP Header parsing feature in Prototype 1.5.0. (The Ajax.Request docs address this capability.)
The sample code below demonstrates the use of the X-JSON header with an simple “sticky notes” web app. On the client-side, the JavaScript is quite simple. The second variable in the onSuccess callback handler will be automatically initialized using the data in the X-JSON header:
function display_note(id) {
new Ajax.Request('/api/note/' + id + '/', {
method: 'get',
onSuccess: function(transport, results) {
alert("Note(" + results['id'] + ") `" + results['title'] + "`: " + results['body']);
},
}
);
}
To handle this request, I’m using Django on the server with the following URL pattern:
(r'^api/note/(?P
The `get_note` method implementation looks like this: [NOTE: For production use, you'll want some exception handling, but I removed the error handling to simplify the example.]
def get_note(request, id):
# Fetch the Note from the DB:
note = Note.objects.get(pk=id)
# Create the response object (with some dummy text for now):
response = HttpResponse('Check the X-JSON header.')
# Manually set the X-JSON header using the JSON generated from the Note record:
response['X-JSON'] = cjson.encode(note.__dict__)
# Return the response object:
return response
If you’d like to use this technique on your own sites, there are couple points to remember:
Yahoo! just launched a new mashup tool called Yahoo! Pipes. The tool allows geek-savvy web users to wire together content filters without writing code. On quick glance, the system reminds me of the way that Apple’s Automator empowers non-programmers (and lazy programmers) to create scripts without writing any AppleScript — only this tool is for wiring together web content. It’s certainly an idea who’s time has come. Even if it doesn’t attract mass usage, it will be successful if it inspires a new level of user control over content, or perhaps a new generation of web tools.
There’s enough detail on the Pipes’ site to get a feel for it, but you might also check out the O’Reilly Radar post, “Pipes and Filters for the Internet” for more.
Here’s a great video on the evolution of the Web:
[Direct link, for the feed readers.]
(Via Gizmodo.)
Just wanted to share this find: After the 1.0 update of FireBug last month, the extension stopped working for me on Firefox 2.0.x on Ubuntu. Thanks to a quick Google search, I found that FireBug conflicts with ColorZilla. After disabling ColorZilla, FireBug now works again.
(Via the comments in: Firebug 1.0: Public Beta, Still Free, and a Lite version for other browsers.)
—
Update 2007-02-08: The author of ColorZilla contacted me, and while we still haven’t isolated the problem, we did find that my ColorZilla extension was at version 0.8.x, and wasn’t finding the 1.0 update. After un-installing and re-installing ColorZilla, it is now somewhat more compatible with FireBug. Both extensions load, and everything except the ColorZilla Eyedropper works.
—
Update: It’s broken again… And once again, disabling ColorZilla got my FireBug working again. I don’t know which extension is causing the problem, but there seems to be a conflict.
I’ve been doing a lot of work lately focused on researching content and Web-service providers, and it’s amazing how differently companies respond to inquiry. As a result, I’ve pulled together a few tips for the budding Web-services entrepreneur’s out there: