Django: How to make a variable available in all templates

Posted in Django, How-To, Programming, Python with tags , on October 31, 2009 by rubayeet

Sometimes when building a web application with Django, you have a common piece of information that is available at all the templates. Foe example, you may have a dynamically built tree menu appearing in multiple templates.  It’s possible to achieve so by adding the data to the context of each template. But that goes against Django’s policy on code reuse. The right way to do that, is to use template context processors and ReuestContext objects.

The sections on Django official documentation are either too short or under misleading headings. So I’m trying to write this in a paint-by-numbers sort of way.

First, the template

Let’s suppose you have the following silly piece of HTML in each of your templates

Hello World! My name is {{name}}

Next, create a custom context processor

Under the directory of your Django application create a new file. Let’s name it ‘custom_context_processors.py’. This is your custom context processor, that will list a number of methods, each of which will have a HttpRequest object as parameter. Suppose you want to have a variable named ‘domain’ available at all template. Let’s add a method to the processor by that name:

define name(request):
   return {'name': 'Django Guru'}

Install the Context Processor

Open settings.py. Add the following line in the TEMPLATE_CONTEXT_PROCESSORS

'myapp.custom_context_processors.domain,'

Add the RequestContext

In your views.py, import the RequestContext module

from django.templates import RequestContext

Now when you render the template using render_to_response() method, a RequestContext object has to be added as the optional context_instance argument. The RequestContext object takes a HttpRequest object as a parameter

def my_view(request):
   #view code
   return redner_to_response('my_template.html', {'foo:bar'}, \
                              context_instance=RequestContext(request))

The variable {{name}} will now be available in my_template.html, without explicitly adding it in the template context. If you need to make it available in some_other_template.html, all you need to do is to pass the RequestContext object as the third parameter to render_to_reponse().

Python equivalent of PHP’s ip2long()

Posted in How-To, Programming, Python with tags , , , , on October 23, 2009 by rubayeet

I’ve been spoiled by PHP! It sometimes makes your job too easy with its large collection of library functions. Python, on the other hand, has a lot of powerful tools for doing low-level stuff. To get something done, which would take a single function call in PHP, you may have to meld together a number of those tools and build a new one.

I was looking for a Python equivalent of PHP’s ip2long() function. which converts an IPv4 address from dotted decimal notation(for example 208.69.34.231) to a 32 bit integer(3494191847). After spending few minutes with Google, I realized that Python has no such function in it’s core or standard library. To achieve this, I had to make use of Python’s socket interface and struct library. Here’s what I did:

from socket import inet_aton
from sturct import unpack

def ip2long(ip_addr):
...ip_packed = inet_aton(ip_addr)
...ip = unpack("!L", ip_packed)[0]
...return ip

Note: Dots(.) in the above code represents indentation. WordPress is eating up the whitespace mysteriously!

The first line inside the ip2long() method, the inet_aton() function, converts the dotted-quad IP address to a 32-bit packed binary format, which is string of four characters in length. To make it an integer, you have to unpack it with the unpack() method, which takes the format as the first argument(which is “!L” in this case, for big-endian unsigned integer) and the packed string as the second. It returns a tuple with  the 32-bit integer as the first element.

To make a long2ip() function you can just reverse engineer the above process with struct.pack and and socket.inet_ntoa.

Back in Gordon Freeman’s Suit!

Posted in Personal, Random Ruminations with tags , on September 30, 2009 by rubayeet

gordon

I am playing PC game again!

It’s Half Life 2 Episode 1!

I know you’re rolling your eyes thinking ‘How 2004 are you? That’s an old game!”.  I know, but I haven’t been around gaming  for a long time. I think I somewhat grew bored of it as I got involved other responsibilities in my personal life.

When I recently got my hands on this game, I couldn’t resist the temptation to play the sequel to one of the best PC games of all time. I booted my PC, which I have been neglecting since the new Macbook Pro came in, installed the game from the DVD, fired it up and started another journey through Half-life’s universe.

There are some cultural changes I have noticed so far. Instead of the legendary crowbar, the game starts with the gravity gun as the first weapon at hand. The biggest change of all, is that Gordon Freeman isn’t alone this time, he has a friend! It’s Alyx Vance!  The ass-kicking chick from Half-life 2. The developers at Valve have designed a sophisticated buddy system, so Alyx is going to fight alongside Gordon throughout the whole game. AI programming in games has come a long way from Daikatana, where moronic activities of your AI controlled buddy(like coming in the line of fire, or firing at you!) made me want to chop that buddy into pieces!

ep1_desktop5_1600x

I’m enjoying the game experience so far. And I’m quite glad that Alyx is with me. I’ve always felt a sense of desperation and fear, as I went through Half Life’s cinematic thrilling environment. That’s why it’s really good that I have Alyx by my side!

Update Finished playing Episode 1 few nights back. It was shorter than I expected but satisfying. Just started to play Episode Two!

Deploying Rails Application on Apache with Phusion Passenger

Posted in How-To, Linux, Rails, Sys Admin with tags , , , , on September 3, 2009 by rubayeet

facebookdc

This morning I put on my system admin hat at work once again. The challenge was to setup a Rails development environment on our production server at the cloud and then deploy a Rails application on Apache.

This article is not really a tutorial, although it’s posted under How-to category. It’s more like a log of my actions in carrying out this task; the problems I faced and what I did to get around them, so that I can trace them back if I ever partake a similar task in future.

Rails have several deployment options and Phusion Passenger a.k.a. Mod Rails is the principle of them. It supports both Apache and the lightweight Nginx Server. Check out there documentation page.

Here’s how it went

Logged into the remote server(CentOS 5.0) using ssh

Installed Rails

gem install -v=2.2.2 rails

Installed MySQL gem

gem install mysql — –with-mysql-include=/usr/include/mysql –with-mysql-lib=/usr/lib/mysql/

Installed Phusion Passenger

gem install passenger


Warning received. Required Software missing

Apache 2 development headers… not found

Installed Apache 2 Development Headers

yum install httpd-devel

Installed Apache module for Passenger

passenger-install-apache2-module

Configured Apache 2 to load the mod_passenger module by adding these lines in /etc/httpd/conf/httpd.conf

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6
PassengerRuby /usr/bin/ruby

Uploaded a sample Rails App(myrailsapp) to /home

Added following lines in /etc/httpd/conf/httpd.conf to create a new virtual host

<VirtualHost *:80>
ServerName rails.myserver.com
DocumentRoot /home/myrailsapp/public
RailsEnv    development
</VirtualHost>

Restart Apache

service httpd restart

Went to http://rails.myserver.com.

Standard Error page for Phusion Passenger displayed. Instructed to consult Apache error log

Checked out the Apache Error Log

cat /etc/httpd/logs/error_log

The last error was

Rails requires RubyGems >= 1.3.1 (you have 1.2.0). Please `gem update –system` and try again.

Updated RubyGems

gem install rubygems-update
update_rubygems

Restarted Apache and went to http://rails.myserver.com again. The following error was showing on the page

no such file to load — sqlite3

Reason: SQLite3-Ruby Gem missing. Tried to install it

gem install sqlite3-ruby

Failed. The system doesn’t have SQLite3 installed

checking for sqlite3.h… no

Installed SQLite3 by building in from source

wget http://www.sqlite.org/sqlite-amalgamation-3.6.17.tar.gz
tar xvzf sqlite-amalgamation-3.6.17.tar.gz
cd sqlite-3.6.17
./configure
make
make install

Installed SQLite3-Ruby Gem

gem install sqlite3-ruby

Restarted Apache and visited http://rails.myserver.com

SUCCESS!