Django 1.0 Web Development Review
Wednesday, 14 October 2009
Django development evolved
For a while now I've been itching to try out Django, it's one awesomely powerful framework, simple and elegant. So thanks to a good friend, Ayman Hourieh sent me a copy of his recent book "Django 1.0 Web Site Development" to review and boy is it a cracking read.
Don't over complicate
Unlike some other books I've read he doesn't try to tackle all the bases at once and then put together the pieces afterwards, he sets out a clearly defined roadmap at the start and builds upon each chapter as you progress; reinforcing what you've learnt with quick review sessions at the end of each chapter.
Starting small he introduces you to the world of Python, it's origins and how & why the Django framework was created. Ayman then runs you through a couple of example lessons to gain your experience with it's fundamentals. This is important as it increases your confidence with the framework and settles you into progressing more, and not pushing you too far too soon. Let's face it with anything new confidence is a big factor and it's important to not try to do too much or embellish too far with details that are little use, and Ayman nails it.
All are welcome
Python is one of those languages, like Ruby or PHP, that doesn't restrict you to a specific o/s and right away he shows you how easy it is to install and setup on Linux / OSX or Windows; you've got to love things like that, good stuff.
Structure
Once done we setup Django, create our first "hello world" project and then review what we've learnt before continuing. Next we go ahead and build a simple social bookmarking application (think of a simple Del.icio.us), we learn about Templates and building up our Database Schema; summarising as we progress.
Next up we handle User Registration. Django comes with a set of default packages which each provide a specific form of functionality to your app, authentication and user management is baked in, others like tagging can be installed as required; it's up to you to decide how you use them.
He bases each chapter on real-world processes, securing your app, tagging, expanding the data schema and adding AJAX functionality with the awesomely powerful jQuery framework. Building on social networking concepts he shows you how to add voting, sharing bookmarks between users and allowing those users to comment on each others posts; before you know it you've got a pretty sterling app going.
Admin and RSS
Next we delve inside Django's built-in administration interface, restricting users, group permissions and crafting the interface more to your application's liking.
We then look at advanced searching and adding RSS news feeds to our application, binding those to our users so each one has their own channel. By using Django's Q objects you can quickly gain a solid understanding of it's Database API and Ayman's examples are pretty easy to follow here.
Deploy
Once we've built a friendship model and an email system, Ayman shows us how to bake in internationalization. This is not a new concept if you've used other frameworks like Rails or CodeIgniter, but he lays it out so easily that the task of translating the phrases is the only headache you get; and being agile we don't get past deployment without putting together some fixtures and automated tests so we have confidence in what we're giving the public.
Conclusion
All in all, for $39.99 (24 quid), you get an easy to understand roadmap that teaches you a good set of fundamentals and takes you from a basic app to something really powerful. At a stretch you could probably complete the app in a week, after which Ayman gives some decent pointers for how to improve it. Weighing in at 250 pages it's perfectly balanced to give you the proper start in this awesome framework.
Great stuff, well recommended
Sinatra on Google AppEngine
Saturday, 12 September 2009
In an effort to try new things out I've always been tempted by Google's AppEngine service, it's free as long as you stay below the thresholds (which as long as it's not facebook v2 you should be ok).
So following Bigcurl's advice here goes...
JRuby
First download and build JRuby from Github
git clone git://github.com/jruby/jruby.git
cd ~/jruby
ant && ant jar-complete
Now check to see what version compiled
bin/jruby -v
=> jruby 1.4.0dev (ruby 1.8.7p174) (2009-09-12 6586) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_15) [x86_64-java]
Install your necessary gems
bin/jruby -S gem install rake sinatra warbler builder rack
Builder is required for xml generation (e.g. sitemap.xml)
JRuby-Rack
Next grab and build JRuby-Rack
cd ..
git clone git://github.com/nicksieger/jruby-rack.git
cd ~/jruby-rack
~/jruby/bin/jruby -S rake SKIP_SPECS=true
Convert Sinatra App
Now re-work your Sinatra app like...
/myapp
.../app.rb
.../config.ru
.../config/warble.rb
.../appengine-web.xml
.../lib
.../public
.../views
Use this gist as a template for your config.ru, app.rb, and appengine-web.xml, config/warble.rb files => http://gist.github.com/91801
Create your AppEngine & Name it
Next create your App in AppEngine, for me I did this via my Google Apps account...
Follow the steps and create your first app, you're allowed a maximum of 10, two points though...
- Once you've created your app you CANNOT delete or rename it
- Make sure you research the security options, once set you CANNOT revoke them
Once an App is deployed you can deactivate the deployment, but unfortunately you cannot delete it, so pick the names wisely.
Personally I use numeric identifiers for my AppEngine Apps, e.g. myapp1, myapp2, myapp3... that way you have a reference to them and they're not tied by name to a specific app, pretty much like savegame slots in an old GameBoy cartridge :-)
Test Your Sinatra App
Once you've copied the settings from that Gist, try out your Sinatra app...
ruby app.rb
Point your browser here to check it's running ok => http://0.0.0.0:4567
SDK
Next grab the AppEngine Java SDK from here
Download and extract it, then copy appengine-java-sdk-1.2.5/lib/user/appengine-api-1.0-sdk-1.2.5.jar to your App's lib directory
Next copy jruby-rack/target/jruby-rack-*.jar to your App's lib directory And copy jruby/lib/jruby-complete.jar to your App's lib directory
Or via Terminal...
~/jruby-rack/target/jruby-rack-*.jar ~/myapp/lib
~/jruby/lib/jruby-complete.jar ~/myapp/lib
Split JRuby
AppEngine, being free, has a 1000 file-limit, so we'll need to do some trickery to get our app deployed.
Following Ola's GIST, create a file in your lib dir split.sh and copy the contents here into it:
#!/bin/sh
rm -rf jruby-core.jar
rm -rf ruby-stdlib.jar
rm -rf tmp_unpack
mkdir tmp_unpack
cd tmp_unpack
jar xf ../jruby-complete.jar
cd ..
mkdir jruby-core
mv tmp_unpack/org jruby-core/
mv tmp_unpack/com jruby-core/
mv tmp_unpack/jline jruby-core/
mv tmp_unpack/jay jruby-core/
mv tmp_unpack/jruby jruby-core/
cd jruby-core
jar cf ../jruby-core.jar .
cd ../tmp_unpack
jar cf ../ruby-stdlib.jar .
cd ..
rm -rf jruby-core
rm -rf tmp_unpack
rm -rf jruby-complete.jar
Run it
sh ~/myapp/lib/split.sh
Giving you your ruby-stdlib.jar file
Hold up, what about Builder ?
For my app, I'm using Builder to generate my sitemap.xml file, so edit config/warble.rb to add this in; along with require 'builder' in config.ru and app.rb
mate config/warble.rb
And include it...
config.gems = ['sinatra', 'builder']
Please continue...
Next pack your application for deployment
cd ~/myapp
~/jruby/bin/jruby -S warble
This should create a tmp folder and a .war file. Since AppEngine needs the exploded war folder and not the .war file, we simply ignore the file
Now edit sinatra.rb:
mate tmp/war/WEB-INF/gems/gems/sinatra-0.9.4/lib/sinatra.rb
And comment out the last like so...
# use_in_file_templates!
Test it Locally
Using the AppEngine SDK we downloaded, use it to test your app...
~/appengine-java-sdk-1.2.5/bin/dev_appserver.sh tmp/war
Point your browser to http://localhost:8080/ and as long as the console returns no errors you should be ok.
Deploy!
Copy your AppEngine's application-id into the appengine-web.xml file, replacing YOUR-APPLICATION-ID
mate appengine-web.xml
Once done, 'warble' your app to add the id to it,
~/jruby/bin/jruby -S warble
Now deploy,
~/appengine-java-sdk-1.2.5/bin/appcfg.sh update tmp/war/
The final app will probably weigh in at 96mb so on a standard ADSL connection will take approx 15-30 minutes to upload, during which you should see something like this:
Reading application configuration data...
2009-09-12 22:05:22.788::INFO: Logging to STDERR via org.mortbay.log.StdErrLog
Beginning server interaction for myapp...
0% Creating staging directory
5% Scanning for jsp files.
20% Scanning files on local disk.
25% Scanned 250 files.
28% Initiating update.
Email: ----
Password ----
31% Cloning 46 static files.
33% Cloning 332 application files.
34% Cloned 100 files.
35% Cloned 200 files.
36% Cloned 300 files.
40% Uploading 142 files.
52% Uploaded 35 files.
61% Uploaded 70 files.
68% Uploaded 105 files.
73% Uploaded 140 files.
90% Deploying new version.
95% Will check again in 1 seconds
98% Will check again in 2 seconds
99% Closing update: new version is ready to start serving.
99% Uploading index definitions.
Update completed successfully.
Success.
Cleaning up temporary files...
Point your browser to http://myapp.blogspot.com and you should see your App, modify url accordingly :-)
What's working on Ruby 1.9
Monday, 20 April 2009
Nice site to track gem compatibility with Ruby 1.9
Was trying to get sqlite3-ruby working but kept failing with...
*** No rule to make target `ruby.h', needed by `sqlite3_api_wrap.o'. Stop.
All I needed was;
sudo aptitude install libsqlite3-dev
On Debian and it was fine again.
sudo gem install sqlite3-ruby
& gem dependent
config.gem 'sqlite3-ruby', :lib => 'sqlite3'
So far got most of the usual gems working on Ruby 1.9, rebuilt my linux setup after I got XP installed. Shrunk down the partition with ntfstools & ntfsresize, then put in Ubuntu 8.10 on the remaining 10GB of my SSD drive.
Gems which work,
actionmailer (2.3.2)
actionpack (2.3.2)
activerecord (2.3.2)
activeresource (2.3.2)
activesupport (2.3.2)
builder (2.1.2)
cgi_multipart_eof_fix (2.5.0)
cucumber (0.3.0)
daemons (1.0.10)
diff-lcs (1.1.2)
eventmachine (0.12.6)
fastthread (1.0.7)
gem_plugin (0.2.3)
libxml-ruby (1.1.3)
mislav-will_paginate (2.3.8)
nokogiri (1.2.3)
polyglot (0.2.5)
rack (0.9.1)
rails (2.3.2)
rake (0.8.4)
rspec (1.2.4)
rspec-rails (1.2.4)
rubygems-update (1.3.2)
sinatra (0.9.1.1)
sqlite3-ruby (1.2.4)
term-ansicolor (1.0.3)
test-unit (2.0.2)
thin (1.0.0)
treetop (1.2.5)
webrat (0.4.4)
Got problems with pony againt tmailer but it's not that big a worry. Cucumber on XP wasn't good, workable but not as good as the real thing on Linux (hence the partitions), for some reason the console filter just didn't like the letter 'a' ;-)
MySQL gem
Found a working mysql gem here
gem sources -a http://gems.github.com
sudo gem install hectoregm-mysql-ruby
require 'mysql'
=> true
The current one's got a lot of problems on Linux
...keep you posted if I find anything else broken
Cucumber Cheat Sheet
Tuesday, 14 April 2009
install cucumber
sudo gem sources -a http://gems.github.com
sudo gem install cucumber
install webrat
sudo apt-get install libxslt1-dev libxml2-dev
..needed by linux
sudo gem install webrat
In your test_helper.rb or env.rb (for Cucumber) add:
require "webrat"
Webrat.configure do |config|
config.mode = :rails
end
install rspec
sudo gem install rspec rspec-rails
gem dependencies + rake commands
add to: config/environments/test.rb
config.gem "rspec", :lib => false, :version => '>=1.2.2'
config.gem "rspec-rails", :lib => false, :version => '>=1.2.2'
config.gem "webrat", :lib => false, :version => ">=0.4.3"
config.gem "cucumber", :lib => false, :version => '>=0.2.2'
sudo rake gems:install :install gems
sudo rake gems:install RAILS_ENV=test :install gems for [test] env
sudo rake gems:build :build gems needing native extensions
sudo rake gems:unpack :unpack gems
sudo rake gems:unpack GEM=hpricot :unpack specific gem
cucumber commands
script/generate cucumber :setup cucumber in your app
cucumber features -n :test against /features
script/generate rspec_model Article title:string content:text
..generate rspec model + db migrations
rake db:migrate :migrate database
rake db:test:clone :clone migrations to test database
script/generate rspec_controller articles index
..generate rspec controller
webrat commands
script/generate integration_test authentication
..generate integration test 'authentication'
rake test:integration :run integration tests
tutorials
beginning with cucumber
- http://railscasts.com/episodes/155-beginning-with-cucumber
- http://asciicasts.com/episodes/155-beginning-with-cucumber
webrat
look inside the /examples directory for help on specific scenarios
commands
rake features :run this to list each scenarios rake tasks
cucumber --help :list cucumber help
...and no, a cucumber is a fruit, not a vegetable
App Engine gets JAVA
Thursday, 09 April 2009
big plus to java developers, Google App Engine's getting JAVA support; along with some extra features.
More here
Going to try getting thin + sinatra on my Joyent Shared Accelerator, had it for a couple of years.
Did some more work with plugins, both matilda and her evil cousin hatchet_harry are less hungry in the memory stakes, still got some way to go but getting there.
Rails Engines
Tuesday, 07 April 2009
How cool are Rails Engines!
With this you can clean up a lot of your code, packaging it into reusable containers you can add-on as needed to future developments. One simple example is making a add-on kit for all the javascript libraries and plugins you regularly use like jquery-kit.
Good stuff & thanks Ryan for the brilliant screencast. If you can't watch the video at work, you can look at it in text format at ASCIIcasts.
Also I recommend peepcode's Plugin Patterns for Rails 2, it's a good complement to this.
Deployment Recipes + GIT on Accelerators + more
Friday, 03 April 2009
Deployment Recipes
on Joyent
Really like this one,
This is a little useful too if your messing with Joyent Shared Accelerators,
Glad to see deprec is still alive & well, was a major help in building slices, playing with the new release on a vm now,
sudo gem install deprec
...and
How-To ?
so in a nutshell
on your server
ssh joe@mygithub.com
Then create somewhere to host all your git repositories,
mkdir git && cd git
And create your remote repository directory and bare git setup
mkdir awesomeapp.git && cd awesomeapp.git
git --bare init
chmod -x ~/git/*/hooks/*
The last line is really important, without it you'll get these kind of errors when pushing an update from the client to the server.
hooks/update: syntax error at line 40: `allowunannotated=$' unexpected
error: hooks/update exited with error code 2
error: hook declined to update refs/heads/master
on your client
Now on your client, create you git repository, add & commit it.
cd awesomeapp
git init
git add .
git commit -m 'init'
Now create the link to your remote repository,
git remote add origin ssh://joe@mygithub.com/users/home/joe/git/awesomeapp.git
And push your update
git push origin master
...now a word from our sponsor
10 Cool Things in Rails 2.3
Friday, 03 April 2009
Posted by Luke Franci, this is an excellent article on the new & startling features within this latest release of the Ruby on Rails framework.
Great work,
CodeKata
Thursday, 19 March 2009
Today I went off to visit Nature Publishing, they've got a good bunch of people down there. Was actually quite beneficial as out of talking I found out about Dave Thomas's CodeKata blog, where he regularly posts ruby problems to make you essentially a better programmer; guess I'll be burning the midnight oil with this one, fun stuff ;-)
- Dave Thomas - Code Kata
.gitignore
Sunday, 08 March 2009
First get git
sudo aptitude install git-core
Then create your .gitignore file to exclude certain files from being versioned.
nano .gitignore
Add what specifics you want to exclude
log/*.log
log*.gz
tmp/**/*
.DS_Store
doc/api
doc/app
Thumbs.db
db/development.sqlite3
db/production.sqlite3
public/cache/*
public/photo/*
index/production/*
The last two are for my html cache directories and sphinx indexing files.
and globally ignore them
git config --global core.excludesfile ~/.gitignore
More here,
sqlite3 on ubuntu
Sunday, 08 March 2009
unlike osx this isn't pre-installed
sudo aptitude install sqlite3 libsqlite3-dev
And the gem for ruby
sudo gem install sqlite3-ruby
Colourful Testing
Saturday, 07 March 2009
So I don't forget more than anything, here's how to colourize your testing output in ZenTest (thanks PeepCode)
sudo gem install ZenTest redgreen
Next go into your rails project and create a file called .autotest
gedit ~/.autotest
And add some styling to AutoTest
require 'redgreen/autotest'
Now everytime you're testing, passed tests will be in green and failures will be in red.
Kick off ZenTest with
autotest
More here










