Commit 03c14040 authored by Michal Čihař's avatar Michal Čihař

Sort languages alphabetically in prefs (issue #204)

Uses PyICU if available, fallback to normal cmp in case it is not.
parent 6813bc06
......@@ -19,13 +19,81 @@
#
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext_lazy as _, get_language
from accounts.models import Profile
from lang.models import Language
from trans.models import Project
from django.contrib.auth.models import User
from registration.forms import RegistrationFormUniqueEmail
from django.utils.encoding import force_unicode
from itertools import chain
try:
from icu import Locale, Collator
HAS_ICU = True
except ImportError:
HAS_ICU = False
def sort_choices(choices):
'''
Sorts choices alphabetically.
Either using cmp or ICU.
'''
if not HAS_ICU:
sorter = cmp
else:
sorter = Collator.createInstance(Locale(get_language())).compare
# Actually sort values
return sorted(
choices,
key=lambda tup: tup[1],
cmp=sorter
)
class SortedSelectMixin(object):
'''
Mixin for Select widgets to sort choices alphabetically.
'''
def render_options(self, choices, selected_choices):
'''
Renders sorted options.
'''
# Normalize to strings.
selected_choices = set(force_unicode(v) for v in selected_choices)
output = []
# Actually sort values
all_choices = sort_choices(list(chain(self.choices, choices)))
# Stolen from Select.render_options
for option_value, option_label in all_choices:
if isinstance(option_label, (list, tuple)):
output.append(u'<optgroup label="%s">' % escape(force_unicode(option_value)))
for option in option_label:
output.append(self.render_option(selected_choices, *option))
output.append(u'</optgroup>')
else:
output.append(self.render_option(selected_choices, option_value, option_label))
return u'\n'.join(output)
class SortedSelectMultiple(SortedSelectMixin, forms.SelectMultiple):
'''
Wrapper class to sort choices alphabetically.
'''
pass
class SortedSelect(SortedSelectMixin, forms.Select):
'''
Wrapper class to sort choices alphabetically.
'''
pass
class ProfileForm(forms.ModelForm):
......@@ -39,6 +107,11 @@ class ProfileForm(forms.ModelForm):
'languages',
'secondary_languages',
)
widgets = {
'language': SortedSelect,
'languages': SortedSelectMultiple,
'secondary_languages': SortedSelectMultiple,
}
def __init__(self, *args, **kwargs):
super(ProfileForm, self).__init__(*args, **kwargs)
......
......@@ -28,6 +28,8 @@ south
http://south.aeracode.org/
libravatar (optional for federated avatar support)
https://pypi.python.org/pypi/pyLibravatar
PyICU (optional for proper sorting of strings)
https://pypi.python.org/pypi/PyICU
Database backend
Any database supported in Django will work, check their documentation for more details.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment