Archive for the 'Computers' Category

Changing the Django Admin site title

Saturday, April 3rd, 2010

Often the Django Admin should look a little different for the sake of your users or for the sake of yourself (running multiple django sites with identical looks and titles can be such a pain). Often users don’t know what Django is, and it takes ages to explain, and even after that they have no clue. Also, often my administration has nothing to do with a website, so I don’t want the text “Site administration”.

First of all, you wanna add templates/admin/base_site.html to your project. This file can safely be overwritten, since it’s a file that the django devs have intended for the exact purpose of customizing your admin site a bit. Here’s an example of what to put in the file:

{% extends "admin/base.html" %}
{% load i18n %}
 
{% block title %}{{ title }}  {% trans 'Some Organisation' %}{% endblock %}
 
{% block branding %}
<style type="text/css">
  #header
  {
    /* your style here */
  }
</style>
<h1 id="site-name">{% trans 'Organisation Website' %}</h1>
{% endblock %}
 
{% block nav-global %}{% endblock %}

This is common practice. But I noticed after this that I was still left with an annoying “Site Administration” on the main admin index page. And this string was not inside any of the template, but rather set inside the admin view. Luckily it’s quite easy to change. Assuming your language is set to English, run the following commands from your project directory:

$ mkdir locale
$ ./manage.py makemessages -l en

Now open up the file locale/en/LC_MESSAGES/django.po and add two lines after the header information (the last two lines of this example)

"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-04-03 03:25+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
 
msgid "Site administration"
msgstr "Main administration index"

After this, remember to run this and reload your project’s server:

$ ./manage.py compilemessages

Django tip: Automatic logins

Friday, February 12th, 2010

In the Django documentation we see the following:

When you’re manually logging a user in, you must call authenticate() before you call login().

That’s all really nice, because it makes sure that all your authentication backends are tried out; but if you want a really quick remedy for getting the job done, then you’ll need to set the user.backend property to the specific backend that authenticated the user. Beware that the Django developers can change these requirements. I wanted this to avoid writing my own backend, so I did this to log users in via a special view accepting a hash from the URL (from an e-mail that had a link that’d automatically log a user in). This could also become useful if you want to become a different user.

def get_hash(s):
    import hashlib
    m = hashlib.md5()
    m.update(str(s) + settings.LOGIN_SECRET)
    return str(m.hexdigest())
 
def auto_login(request, user_id, secret):
 
    user = get_object_or_404(User, id=user_id)
 
    if not secret == get_hash(str(user_id)):
        raise Http404()
 
    user.backend = "django.contrib.auth.backends.ModelBackend"
    login(request, user)
 
    return HttpResponseRedirect(reverse('frontpage'))

BEWARE!
I strongly suggest that you don’t log any superusers in this way. You could add a conditional statement not user.is_superuser or similar.

Uservoice feedback widget: Changing its style

Wednesday, September 30th, 2009

I have a feedback tab that’s blocking vital content on a website. Here’s how to alter the style of the Uservoice Feedback Tab — for instance the vertical offset: You have to insert this AFTER your widget js code, so that it will effectively overwrite the CSS declarations generated by Uservoice. Also it’s pretty annoying that it shows up on printed media, so the last style block is to remove it from print.

<style type="text/css">
  body a#uservoice-feedback-tab,
  body a#uservoice-feedback-tab:link
  {
    margin-top: 10px !important;
  }
</style>
<style rel="stylesheet" type="text/css" media="print">
  body a#uservoice-feedback-tab,
  body a#uservoice-feedback-tab:link
  {
    display: none !important;
  }
</style>

MarkItUp Markdown footnote button

Wednesday, September 9th, 2009

Here’s a simple addition to markItUp, that will prompt the user for a footnote number, a footnote text and then insert the number after the selection and the footnote text at the end of the full text. As handy extra feature, the plugin will save the previous entered footnote and not ask for further numbers during the session, but instead increment the number each time the button is pressed.

Add this to your code to set.js inside your settings object:

{name:'Insert footnote',
	beforeInsert: function(h) {
		instructions = "Type in the number of the footnote:)";
		if (!h.last_footnote) {
			h.last_footnote = prompt(instructions);
		} else {
			if (!isNaN(h.last_footnote))
				h.last_footnote = parseInt(h.last_footnote) +1;
			else
				h.last_footnote = prompt(instructions);
		}
		h.footnote_content = prompt("Type in the text of the footnote:");
	},
	closeWith: function(h) {
		return '[^' + h.last_footnote + ']';
	},
	afterInsert: function(h) {
		h.textarea.value += '[^' + h.last_footnote + ']: ' +
			h.footnote_content;
	}},

And put this icon in the set’s images folder: footnote

After that be sure to modify style.css so it says something like (if 14 was the placement of the footnote button):

.markItUp .markItUpButton14 a	{
	background-image:url(images/footnote.png);
}

Django localized date template filter

Friday, July 10th, 2009

UPDATE! This is going to be redundant in Django 1.2, in which you can add DATE_FORMAT to your django.po files.

I’ve often been frustrated that using settings.DATE_FORMAT does not give a localized date. Granted that the name of a month may be localized, but the format string does not change. So let’s start out by modifying settings.py. We wrap our default date format in a ugettext so the makemessages command will detect it, and we need to make it a dummy function, because the i18n library cannot be imported in settings.py due to circularity (it depends on settings.py).

ugettext = lambda s: s
DATE_FORMAT = ugettext('N j, Y')

Run compilemessages and type in your localized date formats. Now we need a template filter that uses a localized format for calling the Django date format function. This is really simple:

from django.template.defaultfilters import stringfilter
from django.utils import dateformat
from django.utils.translation import ugettext
from django.conf import settings
 
@register.filter()
def localdate(value):
    """Format date with localized date format"""
    format = ugettext(settings.DATE_FORMAT)
    return dateformat.format(value, format)

And done. Using the filter is straight forward:


Date: {{ my_date|localdate }}