Thursday, June 17, 2010

Website design, lessons learned, part 1

I recently got a fortune cookie that said something along these lines:
Skillful actions come from experience. Experience comes from unskillful actions.
Maybe I can share some experience and save somebody a little grief. I anticipate I'll post more things along these lines so I'm calling this "part 1".

I've spent some months building a Django website. The website has been growing more complex and the requirement has been a moving target, so I have been developing practices accordingly.

The first thing is automated testing. We all know it's good, but we don't always remember just how good. Plan your test strategy early.

Django's templating system works well with nested Python dictionaries, so a data structure like
  {"foo":
     {"bar":
         {"baz": "some content here"},
       ... }
   ... }
can be included in an HTML page with a notation like this.
  Let's put {{ foo.bar.baz }} in our web page.
Python dictionaries are essentially the same as JSON data structures. So all my view functions produce nested Python dictionaries, which can either be plugged into HTML templates, or returned as JSON if "json=1" is present in the HTTP request parameters. In the short term, the JSON output makes it very easy to write automated tests that don't have to scrape HTML to find the content. In the longer term, I'll want JSON when I move to AJAX some day.

The second topic is URL design. I've discovered a new way to write spaghetti code -- I've produced a profusion of URLs as I've grown the functionality rapidly. Each URL ("/foo/", "/bar/", "/profile/", etc) has an entry in urls.py and a function in views.py. If you're careless about planning, these tend to sprawl.

I think the right thing is to draw something like a state machine diagram for your website. The nodes are the URLs, each mapping to a HTML page. The edges are the actions users take to go from page to page, clicking buttons or controls or submitting HTML forms. Somewhere in there you need notations for the stuff happening in the back end, things being fetched from the DB or stored, various computations being done, various complex data structures being constructed. My thoughts on how to construct a proper state diagram are not yet complete.