Roshan Book

My Tech Notebook

Django in PHP


This was originally published on http://www.scottgorlin.com/2009/07/embedding-django-in-php/

 

Here’s a quicky I solved while developing this site.  I’m an avid lover of Python and so Django was an obvious framework for this site; however, all the prebuilt goodies like WordPress run in crusty old PHP.  How could I build the custom backends I need without recoding the wheel?
There is a custom TemplateLoader for Django which can read in PHP files or output, seen here and downloadable here.  This ran out of the box for me on Django 1.1 beta (I only had to set PHP_IN_SHELL = False in my settings.py to suppress some header output) but only solves the problem if Django is the primary framework; since this site runs mainly in WordPress I needed another solution.

Enter ModRewrite.  It may be possible to do this entirely within WordPress via $wp_rewrite but I dealt with it directly in my .htaccess file:

AddHandler fcgid-script .fcgi

RewriteEngine On
RewriteBase /

# Static routes
RewriteRule ^(media.*)$ - [L]
RewriteRule ^(adminmedia.*)$ - [L]

# Django stuff
RewriteCond %{REQUEST_URI} !(django.fcgi)
RewriteRule ^(accounts.*)$ /django.fcgi/$1 [L]
RewriteRule ^(photos.*)$ /django.fcgi/$1 [L]
RewriteRule ^(admin.*)$ /django.fcgi/$1 [L]

# From WordPress install
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Options All -Indexes

This, of course, is for Python running through fcgi as required by most shared hosts (Bluehost in my case). A similar solution is likely available via Location and SetHandler tags in an Apache configuration.

All this does now is send my accounts, admin, and photos off to Django.  To actually integrate my photo gallery into WordPress I created a page called ‘photos’ with the permalink http://www.scottgorlin.com/photos, which is the exact url I want my Django app to serve.

Now modify your Django base template system to read the WordPress page instead:

# In some base template
{% extends 'php:loadwp.php' %}
{% block wpwrap %}
My wordpress-wrapped content!
{% endblock %}

# loadwp.php
<?php include('http://scottgorlin.com/index.php?pagename=photos') ?>

I could not get the PHP include to work for the direct url (‘/index.php?…’) but this may be possible with some experimentation. Note that it is important not to use the permalink since that is what we have rerouted through to Django!

Now if you point your browser to the permalink it is handled by Django (and php/WordPress runs in the background), but you still will get the naked PHP page by going through index.php.  All you have to do now is put template code in your WordPress post, ie:

{% block wpwrap %}
{% endblock %}

And you’re done! You can see this in action on my Photos page.

I make no claims about the performance or security of this method, but it’s good enough for my personal site.  Short of using an iframe, the only other method I could derive was using a <?php include(‘djangourl’) ?> within your php code; this works but I couldn’t get user authentication running with this method.

Enjoy!

Leave a comment