Entries with tag django

20
Jan

Two-step authentication with Django

A quick post on django-twostepauth, a package I helped develop. This is a package that enables Django to use token devices for user authentication, like for example the free Google Authenticator available for many mobile phones.

I've been using the two-step token authentication on my gmail account and that reduced my fear of having my email account cracked. I hope other websites, yes I'm thinking of you home banking, start to allow this kind of protection.

If you do not know what two-step authentication is, the video below gives a quick tour of the authentication using the example application shipped with this django package.



The package should be easy to integrate with any website. You can download it from the usual place, or clone it from the repository. As always, feedback is very welcome.

17
Jan

Deploying Compacted Javascript with Django

Here is a small extension to the manage command to make deployment of compacted javascript easier (hopefully).

I think this is better explained with a usage example. I have the templates referring both the standard javascript files for easier debugging and compacted ones for deployment (the debug variable is the standard one and allows the split between development/deployment).

{% if debug %}
  <script src="{{ MEDIA_URL }}js/jquery-1.2.2b.js"
     type="text/javascript"></script>
  <script src="{{ MEDIA_URL }}js/jquery.cookie.js"
    type="text/javascript"></script>
  <script src="{{ MEDIA_URL }}js/jquery.dimensions.js"
    type="text/javascript"></script> 
  <script src="{{ MEDIA_URL }}js/jquery.hoverIntent.js"
    type="text/javascript"></script>
  <script src="{{ MEDIA_URL }}js/jquery.cluetip.js"
    type="text/javascript"></script>
{% else %}
  <script src="{{ MEDIA_URL }}js/jqbase-min.js" 
    type="text/javascript"></script>
{% endif %}

In the settings file I maintain some variables for the JSC command.

JSC_PATH = '/path_to_media/static/js'

JSC_FILES = (
    ('jqbase-min.js',('jquery-1.2.2b.js', 'jquery.cookie.js',
           'jquery.dimensions.js', 'jquery.hoverIntent.js',
           'jquery.cluetip.js')),
    ('jqui-min.js',('ui.mouse.js','ui.draggable.js',
           'ui.draggable.ext.js', 'ui.droppable.js',
           'ui.droppable.ext.js'))
)

# either jsmin or jspacker, defaults to jsmin
JSC_METHOD = 'jsmin'

The first one is the path to the javascript files, the second is a list of compacted filenames and list of files to be included in the compacted one. The third setting is the method to compact the javascript, with options being the jsmin or the jspacker.

Then in the command line I run

./management.py jsc 

to build the compacted files before deployment. Some command line parameters are also available, for example:

./management.py jsc -m jspacker -f jqbase-min.js

The jsc command script (jsmin and jspacker included) must be installed according to these instructions.

I would love to ear about other approaches.

05
Oct

Including variables as templates

To manage the website content in a flexible way it's practical to have some portions of some pages generated from variables created as FlatPages. For example, in a frontpage I have a "featured item" section which renders a flatpage variable.

def frontpage(request):
    fp = FlatPage.objects.get(url='featured')
    return render_to_response('frontpage.html', {'fp':fp })
then in the template
...<div id="featured">{{ fp.content }}</div> ...

But sometimes it would also be nice to put some template tags inside those flatpages. Django does not seem to provide a tag for such task (most probably because it can be a bad idea from the security point of view), but the ssi tag does exactly the same thing for files in the filesystem. Based on ssi, the code bellow defines a new tag that includes the content of a variable as a template.

def do_templatevar(parser, token):
    bits = token.contents.split()
    if len(bits) != 2:
        raise TemplateSyntaxError, "%s tag takes one argument" % bits[0]
    return TemplateVarNode(parser.compile_filter(bits[1]))

register.tag('templatevar', do_templatevar)

class TemplateVarNode(Node):
    def __init__(self, content):
        self.content = content

    def render(self, context):
        content = self.content.resolve(context)
        try:
            t = Template(content)
            return t.render(context)
        except TemplateSyntaxError, e:
            if settings.DEBUG:
                return "[Included template had syntax error: %s]" % e
            else:
                return '' # Fail silently

Now I can put the following code in my flat page

<p>This is my media_url: {{ MEDIA_URL }}</p>

And it will work if I define my template as

...<div id="featured">{% templatevar fp.content %}</div> ...

A last remark to mention databasetemplateloader that allows to load template data from the database. I never tried it, but seems to be a more generic solution (and also a way to have a Zope 1 experience in Django).

29
Sep

Media URL on javascript files

Using the MEDIA_URL setting in a template context variable is a very practical way to have the media files being served from a location defined in the settings file. James Bennett explains here how to define and use this context variable.

But, for example, if I need to have media urls in my javascript files, which are static files, I don't have access to this variable. Take this very simple example. I have a image placeholder in the markup.

<h1>Test 01</h1>
<img id="placeholder" src="">

And the image url is set with javascript.

function set_image() {
    var placeholder = document.getElementById("placeholder");
    placeholder.setAttribute("src","http://localhost:8000/static/django.gif");
}
window.onload = set_image

In this case the full url is hardcoded which, of course is not what I want. Like for the other media files I want to use the above url during development and in deployment switch to the media server url. Something like:

http://media.someserver.com/django.gif

I discuss bellow the approaches I have been trying.

Always use the media server urls in the javascript

Just always using the media server url in the javascript files. It's simple and works fine if I don't need to change the static resources. But changing the static files during development becomes a problem. And developing offline it's also a problem. So it's not a good solution.

Global javascript variable with the media url

This means having the following code in the base template.

<script src="{{ media_url }}test.js" type="text/javascript"></script>
<script language="javascript">var MEDIA_URL = "{{ MEDIA_URL }}";</script>

and in the javascript

function set_image() {
    var placeholder = document.getElementById("placeholder");
    placeholder.setAttribute("src", MEDIA_URL + "django.gif");
}

This approach works, and I consider it more practical than the previous one, but to have a global variable and extra markup is not very clean.

Media url stored in a meta tag

As a variant of the previous approach, instead of creating a global javascript variable I set a meta tag with the location of the media_url.

<meta name="media_url" id="media_url" content="{{ MEDIA_URL }}" />

Then in the javascript file extract the value from the DOM.

document.getElementById("media_url").getAttribute("content");

Again it's not a very clean solution.

Take the media url from the CSS url

This last one is based on convention. I always have the CSS files in the root of my media folder. If the urls for my CSS files are like:

http://media.someserver.com/style.css

then my media url is

http://media.someserver.com/

So in this case the idea is to always fetch the media url from the CSS file url (and so the document must always have a CSS file). The javascript function for such task:

function get_media_url() {
    var css_url = document.styleSheets[0].href;
    var last_slash = css_url.lastIndexOf('/');
    return css_url.substr(0,last_slash+1);
}

Although being based on convention this last one is the one I am more keen on using.

But to be honest, one of the reasons to write this post was to try to find some best practice for this topic. And maybe (hopefully) someone from the community can show some better practice.

26
Sep

Boxes as template tags

With CSS it's very simple to do the markup of a square box. But to make those popular boxes with round corners most approaches use nested divs. For a flexible size box the following markup is typical:

<div class="box">
  <div class="box-outer">
    <div class="box-inner">
      <h2>Headline</h2>
      <p>Content</p>
    </div>
  </div>
</div>

It's a bad idea to repeat this code all over the templates. So a template tag can be a good option. The kind of template that would be interesting to have is one that outputs the boilerplate divs given the headline and the content. Something like:

{% menubox "Box title here" %}
    <p>Content here</p>
{% endmenubox %}

Django makes the writing of this tag very easy and the documentation is very clear. Bellow is the result for such tag.

from django.template import Library, Node, TemplateSyntaxError

register = Library()

def do_menubox(parser, token):
    nodelist = parser.parse(('endmenubox',))
    parser.delete_first_token()
    try:
        tag_name, title = token.split_contents()
    except ValueError:
        raise TemplateSyntaxError, "%r tag requires exactly two arguments" % \
              token.contents.split()[0]
    return MenuboxNode(nodelist, parser.compile_filter(title))

class MenuboxNode(Node):
    
    def __init__(self, nodelist, title):
        self.nodelist = nodelist
        self.title = title
        
    def render(self, context):
        title = self.title.resolve(context)
        output = self.nodelist.render(context)
        return '''<div class="box"><div class="box-outer"><div 
class="box-inner"><h2>%s</h2>%s</div></div></div>''' % (title, output)

register.tag('menubox', do_menubox)

Update: The tag now also works with variable names in the title. The following would output the value of titlevar as the title of the box

{% menubox titlevar %}
    <p>Content here</p>
{% endmenubox %}