Expanding template variables in Django Flatpages

Recently I had to make use of Django's Flatpages framework for a project.  Normally the flatpages framework is fine for a couple pages out of the box but I didn't like the idea of hard coding my media url in the flatpages when it was dynamic everywhere else.  I also wanted to be able to use other tags and filters in the flatpage and have Django render them as usual. 

I didn't want to re-write the flatpages framework (although it's a fairly easy task in Django), rather I wanted to just add one feature.  So how did I do it?  I created a string filter that takes the page content and re-renders it at a template level.  Here's the code:

Starting with the custom filter itself:

from django import template
from django.template import Template, Context
from django.template.defaultfilters import stringfilter
from django.conf import settings
register = template.Library()

@register.filter
@stringfilter
def parse_blocks(value):
    """ use the django template loader and response object to spit 
    out rendered content
    """
    t = Template(value)
    c = Context({ 'MEDIA_URL': settings.MEDIA_URL })
    return t.render(c)

Not the greatest name for the filter I know, but eventually I want it to recognize template blocks.  You can call it what you like. 

Next up the template itself:

{% extends 'base.html' %}
{% load parse_blocks %}

{% block title %}- {{ flatpage.title }}{% endblock %}

{% block content %}
{{ flatpage.content|parse_blocks }}
{% endblock %}

Again pretty self explanatory.  Pass the content as a string to the filter and let the filter do it's job.

A sample flatpage:

<div class="content">
    <img src="{{ MEDIA_URL }}images/image.png" /></div>

You really have to love the ability of Django to make these kind of hacks work without much effort.

Fast, Good or Cheap

I can't tell you how many times I have to explain this to clients.  So I figured I would put up a local copy of this article so it was always on hand as a visual assistant.  Article (I believe) was originally published here.

Below is The Designers Holy Triangle! When creating a project, clients must choose only two out of the three options. They can't have it all. It's a reality of life, clients must deal with it. Web designers must deal with it.

Fast, Good, Cheap

Good + Fast = Expensive

Choose good and fast and we will postpone every other job, cancel all appointments and stay up 25-hours a day just to get your job done. But, don't expect it to be cheap.

Good + Cheap = Slow

Choose good and cheap and we will do a great job for a discounted price, but be patient until we have a free moment from paying clients.

Fast + Cheap = Inferior

Choose fast and cheap and expect an inferior job delivered on time. You truly get what you pay for, and in our opinion this is the least favorable choice of the three.

SSL/Nginx/Django

I wanted to create a client portal of sorts to allow my clients to login and check billing status/history etc.  Since I pre-dominantly program websites in Django that part was a no brainer. But what was troubling me was dealing with the SSL and non-SSL parts.  I had only ever created "secure sites" in the past where everything was behind a login and run over SSL.  It was the flipping back and forth between secure and non that had me a little puzzled on how to implement.

I did some reading and eventually settled (for now) on using nginx (which I use as my main webserver) to look at the paths and redirect as needed:

if ($uri ~ (/bromin|/accounts|/invoices|/sf)) {
    rewrite (.*) https://nomad.ca$1 permanent;
}

So I have one of these blocks in the standard port 80 definition and another in the secure socket definition (with the operator switched to !~ and the rewrite to http).

The only reason I don't like this implementation is that the links in the HTML are not updated. So a link may claim it will take you to a secure page but might redirect to a non-secure page if the SSL isn't needed.  This violates a bit of what I would consider safe coding practice as a prudent user would notice the difference and it may raise suspicion.  However since I haven't even purchased a signed certificate this will do for now.

Google is a little less Evil

Not that I really think Google is evil; today the nay sayers have a little less to gripe about.  Google has announced a new interface into their world of information designed to let you know what they know and track about you with your Google Account.

I took a peek and well, nothing surprising, they know a lot about me.  I don't see Google the same as Microsoft or Facebook and how Google uses my data (so far) is acceptable to me, heck it helps me be productive.  So I provide them with a lot of access to me and my data.  As long as Google keeps releasing these types of transparency tools I will continue to do so.