Hello, my name is Joshua Inkenbrandt and I live in Kansas City, Missouri with my wife and two kids. I'm a Mac guy. I'm a Python guy.

My goal is to make cool stuff that's fun and easy to use.

June 24, 2010

Tornado Tip

I actually discovered this nice little feature when I was up working late one night. When you pass a dictionary into self.write(), it will automatically be JSON encoded and will set the Content-Type header for you.

import tornado.web
import tornado.escape

# Long version
class HelloWorldHandler(tornado.web.RequestHandler):
    def get(self):
        response = dict(error=False, message="Hello World")
        self.set_header('Content-Type', 'text/javascript')
        self.write(tornado.escape.json_encode(response))

# Short version
class HelloWorldHandler(tornado.web.RequestHandler):
    def get(self):
        response = dict(error=False, message="Hello World")
        self.write(response)

April 12, 2010

Tornado's Templates

Tornado is awesome — its documentation at this point isn't. So here's my little contribution to make a great web framework a little easier to develop in.

First things first, Tornado's templates aren't sandboxed like Django's. Meaning it converts your templates into Python code and then executes them with a given context. And there's a benefit in rendering templates as evaluated Python code. Speed. Aside from being fast, I've personally found Tornado's templating syntax to be much easier to write in than Django's, though they are very similar.

But there's also a downside. Templates in Tornado make it possible to do almost anything, including accessing your database, deleting your files, terminating your webserver's instance, etc. These things can actually can be done in Django if you use a custom filter or tag, but straight out of the box, Django protects you from your templates. So a redundant and some-what-obvious word of warning: use discretion when writing your templates in Tornado.

Basic Output

1 Hello, {{ current_user.name }}

Basic Logic

 1 {% if not current_user %}
 2     You're not logged in!
 3 {% elif current_user and curent_user.is_admin %}
 4     Good day, sir!
 5 {% else %}
 6     Howdy!
 7 {% end %}
 8 
 9 {% for link in links %}
10     <a href="{{ link.href }}">{{ link.title }}</a>
11 {% end %}
12 
13 {% set i = 10 %}
14 {% while i %}
15     Item {{ i }}
16     {% set i -= 1 %}
17 {% end %}
18 
19 {% try %}
20     {{ undeclared_var }}
21 {% except NameError, e %}
22     {{ e }}
23 {% end %}

Inheritance

 1 <!-- base.html Template -->
 2 <body>
 3     <div id="main">
 4     {% block main %}
 5         You'll see me if the 'main' block isn't overridden
 6     {% end %}
 7 </body>
 8 
 9 <!-- home.html Template -->
10 {% extends "base.html" %}
11 {% block main %}
12     Now you see me!
13 {% end %}

Comments

1 {% comment "I'm a comment" %}

Includes

1 {% include "other_template.html" %}

Imports

1 {% import os %}
2 {% import sys %}

Setting Variables

1 {% set DEBUG = True %}
2 {% set BASEPATH = os.getcwd() %}

Applying a function to a block

1 {% apply escape %}
2 <h1>Hello World</h1>
3 {% end %}
4 output:  <h1>Hello World</h1>
5 
6 {% apply base64.b64encode %}
7 Base64 Encode Me!
8 {% end %}
9 output: CkJhc2U2NCBFbmNvZGUgTWUhCg==

Caveats

Because the templates are executed as Python code, they follow the same explicit rules as Python. For instance, if you try to access a variable that doesn't exist in scope {{ myvar }} , you'll get a NameError. If you're used to using Django or Jinja, this might throw you off. Also note that every closing block tag is always just {% end %} .

There's a lot more you can do with templates when they're integrated with Tornado's tornado.web.RequestHandler. I would recommend, if you haven't already, giving Tornado a try. It's a perfect combination of simplicity and power.

March 31, 2010

Four Years. A thousand Feelings.

Four years ago today, I said "I do" to the woman standing across from me. I had a lot of questions about how those two words would change my life. Will I be able to meet all her needs? Am I going to feel differently about her when we're old? Is she going to feel differently about me when we're old? What will happen to us when we decide to have kids: what will our lives be like then? Any 20 year old guy would ask himself the same sort of questions.

But Jodi Ann made it easy for me. All I had to do was look into her beautiful blue eyes. She was smiling with excitement, glowing with joy; and after I said the words "I do" she would be all mine. The questions left as soon as they arrived.

So here I am today, four years and two kids later, and I can tell you this: I wouldn't have it any other way. Happy Anniversary, Jodi.