Django Inpage ‘Edit this object’ link

Friday, April 11th, 2008
Converting the Django bookmarklets to on page links to ease the process of editing content on a site.

Django includes some very useful bookmarklets that are accessible through the admin interface. The most helpful one lets you edit the object that is on the page you are currently viewing, assuming you have edit rights. If you haven’t heard about the bookmarklets before I recommend you read the above linked article and try them out.

While the edit object bookmarklet is great it does have a few drawbacks:

  • Each bookmarklet is specific to one site, which is less than convenient if you have multiple Django sites to maintain.
  • You need to add the bookmarklet on every browser you use for every site you want to edit.
  • Not all pages on a Django site can be edited using the bookmarkelets, but the bookmarklet gives no indication as to what pages it can and can’t be used on.

To eliminate those drawbacks I converted the bookmarklet into an on page link. No instead of being tied to bookmark in a browser it’s now tied to the site you want to edit. My script uses the same logic as the bookmarklet but creates a small div positioned in the top right corner of the page on each page with a link to the admin, a link to logout, and most importantly a link to edit the current object. You can see the code below.

 function django_admin_links_div() {
    // Update these variables for your site
    var admin_url = '/admin/';
    var div_title = 'Admin';
    var div_style = 'position: fixed; top: 0; right: 0; border: solid #008999 1px; padding: 3px 5px 3px 5px; text-align: center; color: #000; background: #EEDEBC; font-size: 11px;';
    // end variables to update
    if(typeof ActiveXObject != 'undefined') {
       var x = new ActiveXObject('Microsoft.XMLHTTP');
    }
    else if(typeof XMLHttpRequest != 'undefined') {
       var x = new XMLHttpRequest();
    }
    else {
       return;
    }
    x.open('GET', location.href, false);
    x.send(null);
    try {
       var type = x.getResponseHeader('x-object-type');
       var id = x.getResponseHeader('x-object-id');
    }
    catch(e) {
       return;
    }
    var div = document.createElement('div');
    div.style.cssText = div_style;
    div.innerHTML = '<b><a href="'+admin_url+'">'+div_title+'</a></b><br /><a href="'+admin_url + type.split('.').join('/') + '/' + id + '/">Edit '+type.split('.')[1]+'</a> &nbsp; <a href="'+admin_url+'logout/">Logout</a>';
    document.body.appendChild(div);
}
django_admin_links_div();

In order for this script to work you have to enable the “populate_xheaders” as James Bennett describes. Then just include the above javascript on the pages. I put it at the bottom of my base.html template so it wouldn’t slow down the rendering of the page. I also put the javascript in an if the user is a “staff user” statement, just so it doesn’t download for regular users, but that isn’t technically needed.

{% if user.is_staff %}
    <script type="text/javascript" src="{{ MEDIA_URL }}admin/js/browse_edit.js"></script>
{% endif %}

The third, fourth, and fifth lines of the javascript can be customized to set what the url to the admin site is, what the title of the div should be, and how to style the div.

Read other entries about Django , and Javascript
Written by James Punteney
blog comments powered by Disqus