Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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))
Ejemplo n.º 3
0
    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()
Ejemplo n.º 4
0
    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()
Ejemplo n.º 5
0
    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, '')
Ejemplo n.º 6
0
    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, '')
Ejemplo n.º 7
0
    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))
Ejemplo n.º 8
0
    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