Sublime CodeIntel Configuration for virtualenv

If you are using Sublime Text 2, Sublime CodeIntel is a must have plugin. It provides code intelligence for languages ranging from Python to Javascript with features like code autocomplete and jump to symbol definition.

Working with virtualenv

It supports Python default installation out of the box but if you are working with virtualenv, then you will need to manually configure CodeIntel to pick up your virtual environment.

Configuration files are located at ~/.codeintel/config or project_root/.codeintel/config (you might need to create this yourself). Change the config file like so:

The example above is based on my virtualenv setup, yours might be different. So, please change accordingly.

Managing Django Static Files on Heroku

Deploying and running Django apps on Heroku is really a no-brainer, except for one thing — serving static files via collectstatic.

I run collectstatic as usual, using heroku run command just like how I did it for syncdb. It worked but I’m getting 404 error when serving static files.

It turns out that running collectstatic via heroku run spins up a new dyno and collectstatic is running in an isolated environment. So, all the collected static files are deployed to that location and only for this new dyno and the dyno attached to our Django app can’t access that. — Heroku support staff

Solution

The dead simple solution would be to run collectstatic as part of the Procfile before starting the app. We need to “chain” together our Procfile commands for the web process, like so:

OK there you go, no more 404 error when serving static files from your Django app on Heroku. Plus, every time you deploy your app, newly added static files will be collected automatically.

Update

There are a lot of questions about the configurations. Cross check with my settings.py here http://pastebin.com/H43gRKsJ

Important thing here is your STATICFILES_DIRS. Make sure to include your project_name/app_name/static here. In my case, I have project_name/staticfiles for the STATIC_ROOT. Change STATIC_URL = ‘/static/’ if you want to serve from Heroku, same goes to ADMIN_MEDIA_PREFIX = ‘/static/admin/’

Finally add this to your urls.py in order to serve from Heroku.

urlpatterns += patterns('',
 (r'^static/(?P.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
 )

Files could be access as such:

/app/project_name/staticfiles/style.css > http://flaming-fire-999.herokuapp.com/static/style.css
/app/lib/python2.7/site-packages/django/contrib/admin/media/css/login.css > http://flaming-fire-999.herokuapp.com/static/admin/css/login.css

Please note that this is not the best way to serve static files but it works. One last thing, you still need to go through all these things if you are using django storages and django compressor to serve static files via Amazon S3 because django compressor needs a temp file system cache on Heroku.

Django “Global” Template Variable

Depending on the project you are working on, you might want to access one or more template variables across all your templates like the User object. If you are making news or blog project, one example would be navigation bar item, say a category list.

You might be tempted to pass the category list from your views or create a template tag for that; but that just violate the Django’s DRY principle. So the best way would be through custom context processor. Writing your own is actually very easy.

1. Writing the context processor function.

You can put this function anywhere in your project. My preference is to place this code inside a context_processors.py file under the related app.

# The context processor function
def categories(request):
    all_categories = Category.objects.all()

    return {
        'categories': all_categories,
    }

Note: Each context processor must return a dictionary and takes only one arguement, HttpRequest object.

2. Point it to your TEMPLATE_CONTEXT_PROCESSORS in your settings.py file.

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.contrib.auth.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "django.core.context_processors.request",
    # ...
    "yourapp.context_processors.categories"
)

Now categories is available for use in all your templates.

Done!

Facebook OAuth 2.0 for Canvas App Explained

Facebook is getting better in providing OAuth 2.0 support for its canvas app, that is apps on facebook.com. But one thing that drives people nuts is the documentation. A lot of people getting stuck while trying to adopt the new OAuth authentication method and the Graph API because lack of proper documentation for developers.

This post will explain how simple actually getting OAuth to work with canvas app (both FBML and iFrame). There are two references you need:

  1. http://developers.facebook.com/docs/authentication/
  2. http://developers.facebook.com/docs/authentication/canvas

Authenticating User

The docs on authentication explains that you need to perform two steps to obtain the access_token that is:

  1. Redirect the user to https://graph.facebook.com/oauth/authorize  with your client_id and the URL the user should be redirected back to after the authorization process (redirect_uri)
  2. Exchange it for an access token by fetching https://graph.facebook.com/oauth/access_token. Pass the exact same redirect_uri as in the previous step (1).

For canvas app, it is much more simpler. You do not need to perform step 2. What you need is just step 1, the authorization process. See code below:

After this process, you can parse the signed_request (see below) to get the access_token.

The signed_request

All canvas apps will have this signed_request parameter attached to the callback URL that contains the user_id, oauth_token, expires and profile_id. You need to parse the signed_request to get these info. Example codes can be found here: PHP, .NET (C#), Python, Java.

So, now you are able to parse and get those info, and yes you will get the oauth_token directly. If you get nothing returned (no user_id, oauth_token, etc), don’t freak out. This means the user has not authorize your app yet. So, just perform the authorization process above and you are good to go!

The Good and Bad

The good thing is, it much more simpler — you no longer need to request for a new access_code/access_token when it expires, back and forth. Just parse the signed_request to get the access_token (oauth_token).

The bad thing is, the authorization process doesn’t work well with iFrame-based canvas app. You will get a Facebook inside Facebook effect, that is a Facebook page loaded inside the Facebook frame.

The Workaround for iFrame

The current workaround is using Javascript to load the authorization URL on top:

This will solve part of the problem. After the user authorized your app, Facebook will redirect back to your site specified by the redirect_uri. You will get the problem again (you will see a Facebook logo with a ‘Go to Facebook.com’ link). After much hack-around, I found out that by adding type=’user_agent’ and display=’page’ to the authorization URL, the problem is fixed. See the modified URL below:

There you go.