From 9d58478b2eab232f237c00b848d300f8e8963a05 Mon Sep 17 00:00:00 2001 From: Dirk Eschler Date: Fri, 19 Oct 2012 13:32:33 +0200 Subject: [PATCH] Fixed tabs don't properly support two-part language codes. Resolves issue 63. --- CHANGELOG.txt | 6 +++ modeltranslation/admin.py | 10 ++-- .../js/tabbed_translation_fields.js | 47 ++++++++----------- modeltranslation/utils.py | 43 +++++++++++++++++ 4 files changed, 75 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 43b3ad7..4bf6e12 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,9 @@ +CHANGED: Modeltranslation related css class prefix to 'mt'. + + FIXED: Tabs don't properly support two-part language codes. + (resolves issue 63) + + v0.4.0-beta2 ============ Date: 2012-10-17 diff --git a/modeltranslation/admin.py b/modeltranslation/admin.py index def652b..c859308 100644 --- a/modeltranslation/admin.py +++ b/modeltranslation/admin.py @@ -9,7 +9,8 @@ from django.utils import translation from modeltranslation.settings import DEFAULT_LANGUAGE from modeltranslation.translator import translator from modeltranslation.utils import (get_translation_fields, - build_localized_fieldname) + build_localized_fieldname, + build_css_class) class TranslationBaseModelAdmin(BaseModelAdmin): @@ -56,12 +57,15 @@ class TranslationBaseModelAdmin(BaseModelAdmin): self.model._meta.get_field(orig_fieldname), **kwargs) field.widget = deepcopy(orig_formfield.widget) css_classes = field.widget.attrs.get('class', '').split(' ') - css_classes.append('modeltranslation') + css_classes.append('mt') + # Add localized fieldname css class + css_classes.append( + build_css_class(db_field.name, 'mt-field')) if db_field.language == DEFAULT_LANGUAGE: # Add another css class to identify a default modeltranslation # widget. - css_classes.append('modeltranslation-default') + css_classes.append('mt-default') if (orig_formfield.required or self._orig_was_required.get( '%s.%s' % (db_field.model._meta, orig_fieldname))): diff --git a/modeltranslation/static/modeltranslation/js/tabbed_translation_fields.js b/modeltranslation/static/modeltranslation/js/tabbed_translation_fields.js index 6d9b960..8765116 100644 --- a/modeltranslation/static/modeltranslation/js/tabbed_translation_fields.js +++ b/modeltranslation/static/modeltranslation/js/tabbed_translation_fields.js @@ -16,44 +16,35 @@ var google, django, gettext; /** Returns a grouped set of all text based model translation fields. * The returned datastructure will look something like this: * { - * 'title': { - * 'en': HTMLInputElement, - * 'de': HTMLInputElement, - * 'fr': HTMLInputElement - * }, - * 'body': { - * 'en': HTMLTextAreaElement, - * 'de': HTMLTextAreaElement, - * 'fr': HTMLTextAreaElement - * } + * 'title': { + * 'en': HTMLInputElement, + * 'de': HTMLInputElement, + * 'zh_tw': HTMLInputElement + * }, + * 'body': { + * 'en': HTMLTextAreaElement, + * 'de': HTMLTextAreaElement, + * 'zh_tw': HTMLTextAreaElement + * } * } */ - var translation_fields = $('.modeltranslation').filter( + var translation_fields = $('.mt').filter( 'input[type=text]:visible, textarea:visible').filter( ':parents(.tabular)'), // exclude tabular inlines grouped_translations = {}; translation_fields.each(function (i, el) { - /* - // FIXME: Fails if there's an inline which has the same field name as - // the edited object. - - // Extract fieldname and original language code from class attribute - var css_lang_suffix = 'modeltranslation-field-'; - var name = ''; - var lang = ''; + var field_suffix = 'mt-field-', + name = '', + lang = ''; $.each($(el).attr('class').split(' '), function(j, cls) { - if (cls.substring(0, css_lang_suffix.length) === css_lang_suffix) { - var v = cls.substring(css_lang_suffix.length, - cls.length).split('__'); + if (cls.substring(0, field_suffix.length) === field_suffix) { + var v = cls.substring(field_suffix.length, + cls.length).split('-'); name = v[0]; lang = v[1]; } }); - */ - var name = $(el).attr('name').split('_'), - lang = name.pop(); - name = name.join('_'); if (!grouped_translations[name]) { grouped_translations[name] = {}; } @@ -89,7 +80,7 @@ var google, django, gettext; } container.find('script').remove(); panel = $('
').append(container); - tab = $('' + lang + ''); + tab = $('' + lang.replace('_', '-') + ''); tabs_list.append(tab); tabs_container.append(panel); }); @@ -112,7 +103,7 @@ var google, django, gettext; }); }); $.each(unique_languages, function (i, language) { - select.append($('')); + select.append($('')); }); select.change(function (e) { $.each(tabs, function (i, tab) { diff --git a/modeltranslation/utils.py b/modeltranslation/utils.py index c7dc743..52b6b82 100644 --- a/modeltranslation/utils.py +++ b/modeltranslation/utils.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from django.conf import global_settings from django.utils.encoding import force_unicode from django.utils.translation import get_language as _get_language from django.utils.functional import lazy @@ -33,3 +34,45 @@ def build_localized_fieldname(field_name, lang): def _build_localized_verbose_name(verbose_name, lang): return u'%s [%s]' % (force_unicode(verbose_name), lang) build_localized_verbose_name = lazy(_build_localized_verbose_name, unicode) + + +def _join_css_class(bits, offset): + if ('-'.join(bits[-offset:]) in + [l[0] for l in global_settings.LANGUAGES]): + return '%s-%s' % ('_'.join(bits[:len(bits) - offset]), + '_'.join(bits[-offset:])) + return '' + + +def build_css_class(localized_fieldname, prefix=''): + """ + Returns a css class based on ``localized_fieldname`` which is easily + splitable and capable of regionalized language codes. + + Takes an optional ``prefix`` which is prepended to the returned string. + """ + bits = localized_fieldname.split('_') + css_class = '' + if bits[0] == '': + return '' + if len(bits) == 1: + css_class = str(localized_fieldname) + elif len(bits) == 2: + # Fieldname without underscore and short language code + # Examples: + # 'foo_de' --> 'foo-de', + # 'bar_en' --> 'bar-en' + css_class = '-'.join(bits) + elif len(bits) > 2: + # Try regionalized language code + # Examples: + # 'foo_es_ar' --> 'foo-es_ar', + # 'foo_bar_zh_tw' --> 'foo_bar-zh_tw' + css_class = _join_css_class(bits, 2) + if not css_class: + # Try short language code + # Examples: + # 'foo_bar_de' --> 'foo_bar-de', + # 'foo_bar_baz_de' --> 'foo_bar_baz-de' + css_class = _join_css_class(bits, 1) + return '%s-%s' % (prefix, css_class) if prefix else css_class