There are a few Ruby scripts I use in development of Django sites that I’ve found invaluable. Yeah, some of them are written by friends of mine, but did I mention they’re really smart friends?
Don’t be afraid of the mix!
Most people love to choose one camp over the other – either Django and Python, or Rails and Ruby. But to discount one in loyalty to the other is just silliness. The project I’m currently working on is actually a mix of two web applications – one in Django, and one in Rails. I’m writing the Django part (along with Objective-C, it’s my area of expertise) and a good friend is handling the Rails app. (To be fair, the Rails app existed before Hire an Esquire, but that’s another story.) The experience for the end user will be seamless.
What that’s led to, however, is my introduction to a few really helpful Ruby tools that I’ve integrated in to my development environment.
sprockets.js file which I put in my web page, and I include no other JS files on my site.
Sprockets is amazing with the way it works with Rails, but we’re in a Django environment, so I decided to get it working in my environment. (NOTE: Ruby will have to be installed on your system.) I installed Sprockets gem which also installs the “sprocketize” command-line utility, which is perfect for us. This is the command line I use:
It’s pretty straight forward:
- -I includes subdirectories which hold my dependencies
- hae.js is the “starting point” for compiling my JS code
- > outputs the file to the specified “compiled” JS file
My main JS file,
hae.js looks like this:
At the top I require 3rd party libraries (which I put in a “vendor” subfolder). In this case, it’s
vendor/prototype.s2.js, which Scripty2 provides as a nice combination Prototype/Scripty2 pre-compiled library. Then I declare my default namespace, require the includes of both the appropriately namespaced
hae/hiringagency.js files. Each of those files can have their own requirements for further embedding.
The nice thing is that the requirements are parsed in place, which means that my compiled file will first have Prototype and Scripty2 code, then my currently empty base HAE namespace code, then the contents of the
hae/hiringagency.js files and their dependencies, and finally a
document.observe function that executes dead-last, adding a quick “highlight” function to DOM elements. (Here, Prototype’s
document.observe('dom:loaded', function) is much like JQuery’s
Next I needed to get this to execute dynamically via Python. No problem.
This script sat in my main Django app directory, and uses
os.getcwd() to get the current directory. The path to my JS files uses some basic
Great, now make it happen automatically
We know that Django’s
runserver as well as the much better
runserver_plus utilities have an auto-reloader which reloads the server when any Python code file is saved. I basically wanted the same thing to happen when I saved a JS file.
Thomas pointed me to Kicker, which is a Ruby utility that listens for changes on the OS X filesystem using native FSEvents calls. Point it at a directory, give it a command to execute, and whenever something changes in that directory, run the command.
sprocketize command-line. I installed the Kicker gem as instructed, and tried it out:
I basically took our
Putting it together
In order to really integrate this in to my Django environment, I wanted Kicker to start up whenever I executed the development server
runserver_plus and die off when I closed the server.
This does the following things in order:
sprocketizecommand-line argument, passes that to a string format option to format our Kicker command-line string, and executes it.
start_runserver()which uses the
subprocess.call(...)to block until the subprocess exits.
start_runserver()returns (the subprocess exists) we kill the Kicker subprocess and exit
Now I have a single Python script that will augment
sprockets.js, making it immediately available to my development environment and development server.
I’m now re-using the
sprocketize Python code above in my Fabric Python deploy scripts. I like Fabric’s Pythonic way of deploying builds better than Capistrano – that’s a personal preference – but Sprockets and Kicker didn’t have Python equivalents, so I used Ruby instead – and have a much better dev environment for it.