def __init__(self, *args, **kwargs): # Gets multilingual fields from translation class self.multilingual_fields = get_multilingual_fields(self._meta.model) # Gets default second language from arguments, if informed. Default value is None self.default_second_language = kwargs.pop('default_second_language', self.default_second_language) if self.default_second_language is not None: self.default_second_language = lang_format(self.default_second_language) self.available_languages = map(lang_format, kwargs.pop('available_languages', [code.lower() for code in settings.MANAGED_LANGUAGES])) self.display_language = lang_format(kwargs.pop('display_language', self.display_language)) if self.multilingual_fields: # Change field widgets replacing common TextInput and Textarea to Multilingual respective ones for field_name in self.multilingual_fields: if field_name not in self.base_fields: continue if isinstance(self.base_fields[field_name], forms.CharField): if isinstance(self.base_fields[field_name].widget,forms.Textarea): self.base_fields[field_name] = MultilingualTextField( label=_(self.base_fields[field_name].label), required=self.base_fields[field_name].required) else: self.base_fields[field_name] = MultilingualCharField( label=_(self.base_fields[field_name].label), required=self.base_fields[field_name].required, max_length=self.base_fields[field_name].max_length) super(MultilingualBaseForm, self).__init__(*args, **kwargs) if self.multilingual_fields: # Sets instance attributes on multilingual fields for field_name in (self.multilingual_fields or []): if field_name not in self.fields: continue # Field self.fields[field_name].instance = self.instance self.fields[field_name].default_second_language = self.default_second_language self.fields[field_name].available_languages = self.available_languages self.fields[field_name].display_language = self.display_language # Widget self.fields[field_name].widget.instance = self.instance self.fields[field_name].widget.default_second_language = self.default_second_language self.fields[field_name].widget.available_languages = self.available_languages self.fields[field_name].widget.display_language = self.display_language if self.data: self.fields[field_name].widget.form_data = self.data # Display language for multilingual select widgets # OBS: those aren't multilingual fields from self.multilingual_fields because their # translation is from another model class for field_name in self.fields.keys(): if isinstance(self.fields[field_name], (MultilingualModelChoiceField,)): self.fields[field_name].widget.display_language = self.display_language self.fields[field_name].widget.queryset = self.fields[field_name].queryset self.fields[field_name].widget.label_field = self.fields[field_name].label_field
def render(self, name, value, attrs=None): # Calculates values values = {} for lang in map(lang_format, self.available_languages): # fixme: get from settings # English is the default language if lang == 'en': values[lang] = value # If there is initial value for this field elif self.form_data: values[lang] = self.form_data['%s|%s'%(name,lang)] # If there is an instance (modifying), get translation from it elif self.instance: values[lang] = value # try to remove the formset prefix column = name pattern = re.compile('^[a-z_][a-z0-9_]*-[0-9]+-(.+)$') match = pattern.match(column) if match: column = match.group(1) # Sets the current language to values dictionary values[lang] = self.get_value_by_language(column, value, lang) # If it's adding, translated value is empty else: values[lang] = '' # Creates and renders widgets wargs = self.get_widget_args() widgets, rendereds = [], [] # Sorts the languages list with priority to display language first ordered_languages = ([lang for lang in settings.MANAGED_LANGUAGES_CHOICES if lang_format(lang[0]) == lang_format(self.display_language)] + [lang for lang in settings.MANAGED_LANGUAGES_CHOICES if lang_format(lang[0]) != lang_format(self.display_language)]) for lang,label in ordered_languages: lang = lang_format(lang) widget = self.widget_class(**wargs) widgets.append(widget) # FIXME: get main language from settings w_name = lang == 'en' and name or '%s|%s'%(name,lang) css_class = 'multilingual-value '+lang if lang == self.default_second_language: css_class = ' '.join([css_class, 'default-second-language']) rendereds.append('<div class="%s"><b>%s</b>%s</div>' % (css_class, label, widget.render(w_name, values[lang]))) # FIXME: change multilingual to polyglot return '<div class="multilingual">%s</div>'%('\n'.join(rendereds))
def save_translations(self, obj): """This method is because you can save without commit, so you can call this yourself.""" if not hasattr(obj, 'translations'): return for lang, label in settings.TARGET_LANGUAGES: lang = lang_format(lang) # Get or create translation object try: trans = obj.translations.get(language=lang) except obj.translations.model.DoesNotExist: trans = obj.translations.model(language=lang) trans.content_object = obj # Sets fields values for field_name in (self.multilingual_fields or []): # FIXME: get main language from settings if lang == 'en' or field_name not in self.fields: continue field_name_trans = '%s|%s' % (field_name, lang) if self.prefix: field_name_trans = '%s-%s' % (self.prefix, field_name_trans) if field_name_trans in self.data: setattr(trans, field_name, self.data[field_name_trans]) trans.save()
def save_translations(self, obj): """This method is because you can save without commit, so you can call this yourself.""" if not hasattr(obj, 'translations'): return for lang,label in settings.TARGET_LANGUAGES: lang = lang_format(lang) # Get or create translation object try: trans = obj.translations.get(language=lang) except obj.translations.model.DoesNotExist: trans = obj.translations.model(language=lang) trans.content_object = obj # Sets fields values for field_name in (self.multilingual_fields or []): # FIXME: get main language from settings if lang == 'en' or field_name not in self.fields: continue field_name_trans = '%s|%s'%(field_name,lang) if self.prefix: field_name_trans = '%s-%s'%(self.prefix,field_name_trans) if field_name_trans in self.data: setattr(trans, field_name, self.data[field_name_trans]) trans.save()
def get_value_by_language(self, field_name, value, language): # Returns translation for given language and value try: translation = self.instance.translations.get(language=lang_format(language)) except self.instance.translations.model.DoesNotExist: return '' else: return getattr(translation, field_name, '')
def get_value_by_language(self, field_name, value, language): # Returns translation for given language and value try: translation = self.instance.translations.get( language=lang_format(language)) except self.instance.translations.model.DoesNotExist: return '' else: return getattr(translation, field_name, '')
def render(self, name, value, attrs=None): # Calculates values values = {} for lang in map(lang_format, self.available_languages): # fixme: get from settings # English is the default language if lang == 'en': values[lang] = value # If there is initial value for this field elif self.form_data: values[lang] = self.form_data['%s|%s' % (name, lang)] # If there is an instance (modifying), get translation from it elif self.instance: values[lang] = value # try to remove the formset prefix column = name pattern = re.compile('^[a-z_][a-z0-9_]*-[0-9]+-(.+)$') match = pattern.match(column) if match: column = match.group(1) # Sets the current language to values dictionary values[lang] = self.get_value_by_language(column, value, lang) # If it's adding, translated value is empty else: values[lang] = '' # Creates and renders widgets wargs = self.get_widget_args() widgets, rendereds = [], [] # Sorts the languages list with priority to display language first ordered_languages = ([ lang for lang in settings.MANAGED_LANGUAGES_CHOICES if lang_format(lang[0]) == lang_format(self.display_language) ] + [ lang for lang in settings.MANAGED_LANGUAGES_CHOICES if lang_format(lang[0]) != lang_format(self.display_language) ]) for lang, label in ordered_languages: lang = lang_format(lang) widget = self.widget_class(**wargs) widgets.append(widget) # FIXME: get main language from settings w_name = lang == 'en' and name or '%s|%s' % (name, lang) css_class = 'multilingual-value ' + lang if lang == self.default_second_language: css_class = ' '.join([css_class, 'default-second-language']) rendereds.append( '<div class="%s"><b>%s</b>%s</div>' % (css_class, label, widget.render(w_name, values[lang]))) # FIXME: change multilingual to polyglot return '<div class="multilingual">%s</div>' % ('\n'.join(rendereds))
def __init__(self, *args, **kwargs): # Gets multilingual fields from translation class self.multilingual_fields = get_multilingual_fields(self._meta.model) # Gets default second language from arguments, if informed. Default value is None self.default_second_language = kwargs.pop('default_second_language', self.default_second_language) if self.default_second_language is not None: self.default_second_language = lang_format( self.default_second_language) self.available_languages = map( lang_format, kwargs.pop('available_languages', [code.lower() for code in settings.MANAGED_LANGUAGES])) self.display_language = lang_format( kwargs.pop('display_language', self.display_language)) if self.multilingual_fields: # Change field widgets replacing common TextInput and Textarea to Multilingual respective ones for field_name in self.multilingual_fields: if field_name not in self.base_fields: continue if isinstance(self.base_fields[field_name], forms.CharField): if isinstance(self.base_fields[field_name].widget, forms.Textarea): self.base_fields[field_name] = MultilingualTextField( label=_(self.base_fields[field_name].label), required=self.base_fields[field_name].required) else: self.base_fields[field_name] = MultilingualCharField( label=_(self.base_fields[field_name].label), required=self.base_fields[field_name].required, max_length=self.base_fields[field_name].max_length) super(MultilingualBaseForm, self).__init__(*args, **kwargs) if self.multilingual_fields: # Sets instance attributes on multilingual fields for field_name in (self.multilingual_fields or []): if field_name not in self.fields: continue # Field self.fields[field_name].instance = self.instance self.fields[ field_name].default_second_language = self.default_second_language self.fields[ field_name].available_languages = self.available_languages self.fields[ field_name].display_language = self.display_language # Widget self.fields[field_name].widget.instance = self.instance self.fields[ field_name].widget.default_second_language = self.default_second_language self.fields[ field_name].widget.available_languages = self.available_languages self.fields[ field_name].widget.display_language = self.display_language if self.data: self.fields[field_name].widget.form_data = self.data # Display language for multilingual select widgets # OBS: those aren't multilingual fields from self.multilingual_fields because their # translation is from another model class for field_name in self.fields.keys(): if isinstance(self.fields[field_name], (MultilingualModelChoiceField, )): self.fields[ field_name].widget.display_language = self.display_language self.fields[field_name].widget.queryset = self.fields[ field_name].queryset self.fields[field_name].widget.label_field = self.fields[ field_name].label_field