#!/usr/bin/env python # -*- coding: UTF-8 -*- """ Title: Choices Author: Will Hardy (http://willhardy.com.au/) Date: November 2007 Description: A convenient but complicated Choices tool. Problems: xgettext probably wont find your strings to be translated. This is an uncomfortable problem. """ from django.utils.translation import ugettext as _ class Choices(tuple): """ A more readable, convenient way of declaring translatable choices. """ def __new__(cls, *args, **kwargs): # Create a normalised dictionary of items items = {} order_list = [] # Add the keyword arguments as is items.update(kwargs) # Add the non-keyword arguments, enumerating them automatically for value, name in enumerate(args): # Avoid clashes in the automatically generated values # Explicit values (in the keyword arguments) are allowed to clash while value in items.values(): value += 1 items[name] = value order_list.append(name) # keyword arguments come last sorted_keywords = [ (value, key) for key, value in kwargs.items() ] order_list.extend([ key for value, key in sorted(sorted_keywords) ]) # Create the actual choices list choices = [] for name in order_list: choices.append((items[name], _(name))) # Save the choices list as a tuple self = super(Choices, cls).__new__(cls, choices) # Add our stored value to the object for reference for name in order_list: # Remove all non-alphanumeric characters, replace with non-repeating underscore key = "_".join("".join([ a.isalnum() and a or " " for a in name]).split()).upper() setattr(self, key, items[name]) # Add our dictionary of items for reference self._items = items self._order_list = order_list return self def __repr__(self): """ Displays a way of re-creating this object. """ return "Choices(%s)" % ", ".join([ "%s=%s" % (name, self._items[name]) for name in self._order_list ] )