Goodies from tornado-utils - part 2: tornado_static

22 September 2011   0 comments   Tornado

Mind That Age!

This blog post is 6 years old! Most likely, it's content is outdated. Especially if it's technical.

Powered by Fusion×

This is Part 2 in a series of blogs about various bits and pieces in the tornado-utils package. Part 1 is here


Code is here

This code takes care of two things: 1) optimizing your static resources and 2) bundling and serving them with unique names so you can cache aggressively.

The trick is to make your development environment such that there's no need to do anything when in "debug mode" but when in "production mode" it needs to be perfect. Which files (e.g. jquery.js or style.css) you use and bundle is up to you and it's something you control from the templates in your Tornado app. Not a config setting because, almost always, which resources (aka. assets) you need is known and relevant only to the templates where you're working.

Using UI modules in Tornado requires a bit of Tornado-fu but here's one example and here is another (untested) example:


import tornado.web
from tornado_utils.tornado_static import (
  StaticURL, Static, PlainStaticURL, PlainStatic) 

class Application(tornado.web.Application):
   def __init__(self):
       ui_modules = {}
       if options.debug:
           ui_modules['Static'] = PlainStatic
           ui_modules['StaticURL'] = PlainStaticURL
           ui_modules['Static'] = Static
           ui_modules['StaticURL'] = StaticURL

       app_settings = dict(

       handlers = [
         (r"/", HomeHandler),
         (r"/entry/([0-9]+)", EntryHandler),
       super(Application, self).__init__(handlers, **app_settings)

def main(): # pragma: no cover
   http_server = tornado.httpserver.HTTPServer(Application())

if __name__ == "__main__":

Note! If you're looking to optimize your static resources in a Tornado app you probably already have a "framework" for setting up UI modules into your app. The above code is just to wet your appetite and to show how easy it is to set up. The real magic starts to happen in the template code. Here's a sample implementation:

<!doctype html>
       <title>{% block title %}{{ page_title }}{% end %}</title>
       <meta charset="utf-8">
       {% module Static("css/ext/jquery.gritter.css", "css/style.css") %}
   {% block content %}
   {% end %}
   {% module Static("js/ext/head.load.min.js") %}
   var POST_LOAD = '{% module StaticURL("js/dojo.js", "js/dojo.async.js") %}';

What you get when run is a template that looks like this:

<!doctype html>
       <title>My title</title>
       <meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="//">

(Note that this will create a whitespace optimized filed called "" in "/tmp/combined")

Have a play and see if it makes sense in your app. I do believe this can do with some Open Source love but so far it works great for me on Kwissle, DoneCal and TooCoolFor.Me


Thank you for posting a comment

Your email will never ever be published

Related posts

Goodies from tornado-utils - part 1: TestClient 20 September 2011
Goodies from tornado-utils - part 3: send_mail 24 September 2011
Advanced Closure Compiler vs UglifyJS2 20 January 2016
Goodies from tornado-utils - part 3: send_mail 24 September 2011
Goodies from tornado-utils - part 1: TestClient 20 September 2011
Comparing Google Closure with UglifyJS 10 July 2011
Local Django development with Nginx 11 October 2010
The awesomest way possible to serve your static stuff in Django with Nginx 24 March 2010
Optimize with 15 February 2005
Loadtesting this site and compare with static Apache 15 October 2003