Chicken Scratches: Developing ideas on developing.

Eddie’s Django Tip #2: Don’t Get Trapped

May 10th, 2011 by Eddie Sullivan

This is the second in my series that I am calling “Eddie’s Practices” for Django, in which I present tips and tricks that I have gleaned over the years of working with the Django web application framework. If you haven’t seen Eddie’s Django Tip #1: Choose Names Carefully, why not take a look at it now?

Today’s tip is:

Don’t Get Trapped in the Django Universe

Hubble RoseOne of Django’s strengths is its “batteries included” approach. It provides for free many of the features you would normally have to write from scratch or cobble together from disparate sources. Some examples are the authentication system, the administrative interface, and the templating system. These are wonderfully useful, and they often work together in ways that separately developed libraries can not. However, not every part of Django will fit your needs all the time. Choices were made in the design of Django, and those aren’t always the same choices you would have made.

Fortunately, another strength of Django is its modularity. It is very easy to unplug one of its built-in features and plug in your own or someone else’s. I’ll go through some of the Django features that you may want to consider replacing or eliminating.

The important point I want to emphasize is that there is nothing unclean or dangerous about doing this. It’s your site, you’re the boss of Django, and you should only use the parts of it that you need. I think the creators of Django would agree with me.


Django: Eddie’s Practices #1: Choose Names Carefully

May 3rd, 2011 by Eddie Sullivan

Why “Eddie’s Practices?”

Django has become one of the more popular web frameworks out there. I have been lucky enough to have worked with it for many years, starting in its early beta stages. I’ve used it to create many web applications on my own, and I’ve worked on many apps that were originally created by others.

django-logo-positiveAs in most development environments, there are certain common issues that pop up again and again. Over the years, through trial and error, talking to other developers, and a lot of hard thinking, I’ve come up with some general approaches to many of these issues.

I have gotten a great response to my previous posts about Django, so I decided to create a new series of posts, dealing with these tips and techniques. I wouldn’t have the hubris to call these “best practices,” because that would imply that my way is best for all developers. So I’ll just go with “Eddie’s Practices.” These are things that work for me, things I wish people had told me when I was starting out. I hope they work for you, too. Mileage may vary, as they say.

Tip #1: Think hard about what to name your project and your app.

We’ll start with a basic one, but one that seems to come up over and over. When you get started with Django, you create a “project,” and then within that project you create an “app.” You need to come up with names for both of them. This may seem a trivial point – surely an app by any other name would be just as enterprisy. But it can affect your future development in unexpected ways.

The Dangers of Knowing Too Much

April 22nd, 2011 by Eddie Sullivan

Lady GagaApple recently announced that they will be offering a “Music in the Cloud” service, whereby users can upload their music library to a server and access it from anywhere with an internet connection.

My first thought was, “So what?” but then I read that Google is also working on a similar service, and in fact the two companies were in a race to see who could launch it first. So apparently two of the smartest companies out there think this is a good idea. Given Apple’s recent track record, I’m going to guess it’s a good bet.

While I believe them that it’s a good idea, I will never use it, and I would never have thought of it. Why not? Because I don’t need it. I have my ten-dollar-a-month Dreamhost account on which I host this website and a bunch of others. My account was granted unlimited storage for life to make up for some billing mix-up a couple years back, so all I need is rsync, ssh, and a couple Perl scripts and I can have the same functionality without the privacy concerns of using Apple or Google’s service. If I want a slick streaming web interface, well that’s easy with some Django-based magic and an open-source Flash media player – I can even customize its source code! So why would anyone need a third-party music streaming service?

What’s that? You mean not everybody knows Perl? Not everybody manages web apps for a living? Not everybody cares about privacy?


How NOT to Hire an Engineer

April 15th, 2011 by Eddie Sullivan

iPhonesThe Wall Street Journal recently published an online article headlined Mobile App Talent Pool Is Shallow. In this article, Joe Light discusses the problem that a lot of Smartphone app companies think they have: they believe there are not enough engineers with experience developing software for mobile applications.

A software developer reading that article may jump at the perceived opportunity: Hey, I better learn iOS, or Android, or Windows Phone 7, or something! A recruiter reading that article may experience a feeling of dismay: Crap, there’s nobody who can do what we need doing! They would both be wrong.


Introducing Play Scopa: a new Scopa card game site

September 28th, 2010 by Eddie Sullivan

card-logo I have previously written about the Scopa game I developed for Facebook. Well, I became frustrated with the technical limitations of the Facebook canvas platform, and decided to move it off of Facebook onto its own site. So now you can practice your Italian and learn a new card game at You can still log in with your Facebook account, though.

If you’ve never heard of Scopa, it’s a fun Italian card game for two or more people. You can play with one of two gorgeous Italian decks of cards or a standard American deck with the face cards removed. There is a section on the site where you can learn how to play Scopa as well. You can practice by playing against the computer, and the game also has a “beginner” level where the computer will give you hints about what moves you can make next.

For my technical audience, the site is implemented in Python and Django on the back end. The game play is completely handled in HTML and JavaScript, using the Comet technology for real-time player-to-player communication. The back end server is my custom-built Sully Server (soon to be released as open-source).

Enjoy, and go play Scopa!

Auto-closing Django template tags in Emacs

July 7th, 2008 by Eddie Sullivan

I have written two previous articles about how I edit Django template files in Emacs and XEmacs.
Here is
I edit Django templates
. And here
is More
on editing Django templates in XEmacs
. Here today is another
little tip that can be used in conjunction with those two other
posts or independently.

Django templates involve a lot of punctuation. Between the angle
brackets and slashes of HTML and the curly braces and percent
signs of the Django template language, it’s enough to make your
pinky fingers hurt just thinking about it. Therefore any little
trick to reduce some of this typing burden can be
helpful. Presented here is some Emacs Lisp code to provide
auto-closing of Django template tags. So even if you still have
to type things like curly-brace percent-sign space ifequal blah
blah2 percent-sign close-curly-brace
, you won’t have to type the
{% endifequal %}. (Of course, if you’re using
the abbrev tips I gave previously, you won’t even need
to type the opening tag very often, but sometimes you still do.)


What’s Wrong with Flying: How the internet killed travel

June 22nd, 2008 by Eddie Sullivan

Air travel is in a downward spiral. Not literally of course, but
clearly and consistently, and everybody knows it. The airlines know
it, the airline employees know it, travel agents found out a while
ago, and consumers sure as Hell know it. There are a lot of reasons
for it, but this post talks about just one:

Airlines claim the degradation in quality comes from increased
competition. They say they are forced to cut corners and reduce
features in order to stay competitive. Does this make sense?


Python templates – Django and Cheetah

May 28th, 2008 by Eddie Sullivan

When writing web applications, sooner or later (usually sooner),
everybody is going to need a template
language. String-interpolation just doesn’t cut it. We
need a way to write something that is almost all text
(or HTML, or XML, or whatever), but with some dynamic pieces
thrown in.

Since this need is so universal, and the basic requirements are
so easy to describe, many different groups of people have taken
it upon themselves to create Yet Another Template Language. As
developers, we can join the fray and roll our own, or we can
wade through the myriad options available to us to find the one
that meets our needs or philosophy. Those who use PHP or ASP
pretty much have the choice made for them, since the languages
themselves are glorified template processors. Python
programmers have a lot more options.

Here I’m just going to focus on the two Python templating
languages I have used in real applications: Cheetah and the
Django templating engine. (Django, of course, is more than
just templates, but the template subsystem can be used
independently.) I use and enjoy both of these, but there are
significant differences that are worth comparing and
contrasting, when deciding which to use for your particular
needs. There are other comparisons out there, including one by
the Benevolent Dictator for Life
himself (though that’s a bit
out of date and inaccurate). When choosing which to use, you
should read as many opinions as you can, then make the decision
yourself. Presented here are just my personal thoughts.


CSS: A one act play

April 16th, 2008 by Eddie Sullivan

Student: I just learned CSS and I’m very excited about it! It seems like a nice clean and logical way to do layout. Look, I can just say color:red and my text turns red.

Guru: Oh yes, it’s soo much better than using tables. Tables are bad, bad, bad! Never use tables!! You’ll ruin us all!!!

Student: Um, ok. No tables. But say, I have a question. I’m trying to make my links look like buttons, but when I set a width on them nothing happens. What’s that all about?

Guru: Duh! Don’t you know, you can’t set a width on an inline element? You have to set display:block .

Student: Ah, I see. So now I can set the width, but it just puts each link on a separate line by itself. What if I want three or four on the same line? They’re not very wide after all. Could I maybe just use a ta-

Guru: Nooooo! No tables, I said! Look, it’s very easy and logical. Just set a fixed width and set float:left on all the items you want on the same line. Why would you not think of that?

Student: Ah, of course, float:left . I guess that should have been obvious.

Guru: Very good.

Student: But wait.

Guru: Now what is it?

Student: Now my buttons are all squished up with the text that comes after them, even if I put a <br> tag after them. Why is it ignoring my <br> tag?

Guru: Don’t you know? You should never use the <br> tag! That’s mixing layout with content. It doesn’t work after floated elements, anyway. You have to make an empty <div>, put it after all the buttons, and set clear:both on it.

Student: Ah, of course. Why didn’t I think of that? We wouldn’t want to have extra markup who’s sole purpose is for layout, would we?

Guru: Of course not. Empty divs and wrapper divs don’t count. At least they’re not tables.

Student: Ok, now how do I center them?

Guru: What?

Student: I want to center my table of buttons. How do I do that?

Guru: Well, first of all, it’s not a “table” of buttons. Don’t ever let me hear you use that word again. It’s a “list” of buttons. Turn them into a list. Then it’s very easy to center them. Set list-style-type:none. Then set display:table, but only in Firefox. You need to use conditional HTML comments for IE. Then set margin-left:auto. That’s how we center things, of course. Oh yeah, and you have to enclose the whole thing in another wrapper <div>. Then set text-align:center on the wrapper. See, easy as pie. Aren’t you glad we’re not in the bad old days, when we used to have to write hacky HTML just to make the layout work?

Student : Maybe I’ll go into marketing. (exit stage left)

More on editing Django templates in XEmacs

March 27th, 2008 by Eddie Sullivan

Previously, I wrote about how I set up syntax-highlighting for
Django template files using MMM (multiple major modes) in
. This entry builds on the previous one, so if you haven’t
read that one, I suggest doing so now.

This post addresses the age old question, “If (X)Emacs is so
good, why can’t it do the typing for me?” Well, the answer, of
course, is it can. You just have to write a few lines of Lisp
first. Or you can copy and paste the Lisp code off of sites like
this one. ;)

Introducing dynamic abbreviations

Pressing M-/, (that is, holding down the Alt key and
pressing the forward slash key), runs the command
dabbrev-expand, which tries to finish whatever word you
are in the middle of typing. For example, if as I’m typing this
entry, I type the letter d, then press M-/,
“dabbrev-expand” shows up, because that was the last word I
typed that started with d. If I then type M-/
again, “dabbrev-expand” changes to “down”. If I keep pressing
it, the word cycles through different guesses for what I’m going
for. If you’ve ever used VisualStudio, you may see some
similarities to the Intellisense feature. I find I almost never
type a whole word anymore, I’ve become so dependent on dynamic

Templates and more abbreviations

dabbrev-expand is useful to avoid having to type long
words over and over, but there are also longer patterns that
seem to need typing frequently. Thats where the tempo
package comes in handy, especially when combined with the
abbrev library. Here is some documentation for
. Here is some documentation for abbrev.

Essentially, tempo allows you to specify “templates,” or
blocks of standard text that can be parameterized as they are
filled in: the same concept as Django templates, but meant for
interactive use. From now on, I will say “tempo template” or
“Django template” to avoid confusing the two types.

abbrev lets you define your own pre-set abbreviations,
which can be filled in automatically as you type or upon
request. This can be combined with tempo to do some
pretty powerful stuff very easily.

I have a few Django-specific tempo templates and abbrevs set up
in my XEmacs initialization file. For example, as soon as I type
“{% block” followed by a space, the entire framework of a Django
template block is filled in for me. I’ve also added a special
menu to the menu bar for tempo templates I use frequently.

HTML and templates can be very repetitive, so I’ve found this
saves me a lot of typing.

My initialization file

Here is the subset of my ~/.xemacs/init.el file. This includes
the mmm-mode stuff I discussed last time, as well as the
tempo templates and abbrevs. I haven’t put a tempo template for
every possible Django template tag, just the ones I use most
frequently. I’ll leave further extension as an exercise for the

Also, some people don’t like the expansion to happen
automatically as they are typing. To turn this off, comment out
the line that says “(setq abbrev-mode t)” by putting a semicolon
(;) in front of it. Then you can
manually expand tempo templates by pressing C-\

Once again, this is known to work in XEmacs version 21.4 on
Windows XP. It will most likely work in other versions of
XEmacs, and possibly in GNU Emacs.

;; CSS-Mode
(autoload 'css-mode "css-mode" "Mode for editing CSS files" t)
(add-to-list 'auto-mode-alist '("\\.css\\'" . css-mode))
(setq cssm-indent-function #'cssm-c-style-indenter)
(setq cssm-indent-level '2)

;; Use hm--html-mode for files that end in .tmpl (Django templates)
(add-to-list 'auto-mode-alist '("\\.tmpl\\'" . hm--html-mode))

;; Multiple Major Modes.
(require 'mmm-vars)
(require 'mmm-mode)
(require 'mmm-sample)
(setq mmm-global-mode 'maybe)

;; Custom MMM classes for Django templates
    :submode python-mode
    :face mmm-declaration-submode-face
    :front "{%"
    :back "%}"
    :include-front t
    :include-back t)))

    :submode python
    :face mmm-output-submode-face
    :front "{{"
    :back "}}"
    :include-front t
    :include-back t)))

(mmm-add-mode-ext-class nil "\\.tmpl\\'" 'embedded-css)
(mmm-add-mode-ext-class nil "\\.tmpl\\'" 'my-django-var)
(mmm-add-mode-ext-class nil "\\.tmpl\\'" 'my-django-expr)
(mmm-add-mode-ext-class nil "\\.tmpl\\'" 'html-js)

;; Use different colors for different sub-modes.
(setq mmm-submode-decoration-level 2)
;; Make the code submode a little more readable.
(set-face-background 'mmm-code-submode-face "#EEEEFF")

;; Tempo templates and abbrevs

;; Control-backslash to expand a tempo template manually.
(global-set-key "\C-\\" 'tempo-complete-tag)

(require 'adapt) ; Must be done before hm--html for some reason.
(require 'hm--html-mode) ; Needed for hm--html-mode-abbrev-table
(require 'tempo) ; Tempo templates.

;; Expands <span into an HTML span with a class defined.
(tempo-define-template "span"
                       '("<span class=\"" (p "Class? ") "\">" r "</span>" >)
                       "<span "
                       "Insert a template for a span with a class")
(define-abbrev hm--html-mode-abbrev-table
  "<span" "" 'tempo-template-span)

;; Expands <script into an HTML javascript block.
(tempo-define-template "script"
                       '(> "<script type=\"text/javascript\">" r "</script>" > %)
                       "<script "
(define-abbrev hm--html-mode-abbrev-table
  "<script" "" 'tempo-template-script)

;; Expands a Django template block.
(tempo-define-template "block"
                       '("{% block " (p "Block name? ") " %}" p "{% endblock %}")
                       "{% block "
(define-abbrev hm--html-mode-abbrev-table
  "{% block" "" 'tempo-template-block)

;; Expands a Django template if tag.
(tempo-define-template "django-if"
                       '("{% if " (p "Conditional? ") " %}" p "{% endif %}")
                       "{% if "
(define-abbrev hm--html-mode-abbrev-table
  "{% if" "" 'tempo-template-django-if)

;; Expands a Django template for tag.
(tempo-define-template "django-for"
                       '("{% for "
                         (p "Variable? ") " in "
                         (p "List? ") " %}" p
                         "{% endfor %}")
                       "{% for "
(define-abbrev hm--html-mode-abbrev-table
  "{% for" "" 'tempo-template-django-for)

;; Create a menu for inserting these templates.
(defun add-templates-menu ()
  (add-submenu nil '("Tem%_plates"
                     ["{%% %_block %%}" tempo-template-block]
                     ["{%% %_if %%}" tempo-template-django-if]
                     ["{%% %_for %%}" tempo-template-django-for]
                     ["<%_span>" tempo-template-span]
                     ["<s%_cript>" tempo-template-script])))

;; When entering hm--html-mode, turn on abbrevs and add the template menu.
(add-hook 'hm--html-mode-hook
          (lambda ()
            (setq abbrev-mode t)