Beispiel #1
0
class AdvancedSettingsForm(forms.ModelForm):
    from cms.forms.fields import PageSmartLinkField

    _user = None
    _site = None
    _language = None

    application_urls = forms.ChoiceField(
        label=_('Application'),
        choices=(),
        required=False,
        help_text=_('Hook application to this page.'))
    overwrite_url = forms.CharField(
        label=_('Overwrite URL'),
        max_length=255,
        required=False,
        help_text=_('Keep this field empty if standard path should be used.'))

    xframe_options = forms.ChoiceField(
        choices=Page._meta.get_field('xframe_options').choices,
        label=_('X Frame Options'),
        help_text=_(
            'Whether this page can be embedded in other pages or websites'),
        initial=Page._meta.get_field('xframe_options').default,
        required=False)

    redirect = PageSmartLinkField(
        label=_('Redirect'),
        required=False,
        help_text=_('Redirects to this URL.'),
        placeholder_text=_('Start typing...'),
        ajax_view='admin:cms_page_get_published_pagelist')

    # This is really a 'fake' field which does not correspond to any Page attribute
    # But creates a stub field to be populate by js
    application_configs = forms.CharField(
        label=_('Application configurations'),
        required=False,
        widget=ApplicationConfigSelect,
    )
    fieldsets = ((None, {
        'fields': ('overwrite_url', 'redirect'),
    }), (_('Language independent options'), {
        'fields': (
            'template',
            'reverse_id',
            'soft_root',
            'navigation_extenders',
            'application_urls',
            'application_namespace',
            'application_configs',
            'xframe_options',
        )
    }))

    class Meta:
        model = Page
        fields = [
            'template',
            'reverse_id',
            'overwrite_url',
            'redirect',
            'soft_root',
            'navigation_extenders',
            'application_urls',
            'application_namespace',
            "xframe_options",
        ]

    def __init__(self, *args, **kwargs):
        super(AdvancedSettingsForm, self).__init__(*args, **kwargs)
        self.title_obj = self.instance.get_title_obj(
            language=self._language,
            fallback=False,
            force_reload=True,
        )

        if 'navigation_extenders' in self.fields:
            navigation_extenders = self.get_navigation_extenders()
            self.fields['navigation_extenders'].widget = forms.Select(
                {}, [('', "---------")] + navigation_extenders)
        if 'application_urls' in self.fields:
            # Prepare a dict mapping the apps by class name ('PollApp') to
            # their app_name attribute ('polls'), if any.
            app_namespaces = {}
            app_configs = {}
            for hook in apphook_pool.get_apphooks():
                app = apphook_pool.get_apphook(hook[0])
                if app.app_name:
                    app_namespaces[hook[0]] = app.app_name
                if app.app_config:
                    app_configs[hook[0]] = app

            self.fields['application_urls'].widget = AppHookSelect(
                attrs={'id': 'application_urls'},
                app_namespaces=app_namespaces)
            self.fields['application_urls'].choices = [
                ('', "---------")
            ] + apphook_pool.get_apphooks()

            page_data = self.data if self.data else self.initial
            if app_configs:
                self.fields[
                    'application_configs'].widget = ApplicationConfigSelect(
                        attrs={'id': 'application_configs'},
                        app_configs=app_configs,
                    )

                if page_data.get(
                        'application_urls', False
                ) and page_data['application_urls'] in app_configs:
                    configs = app_configs[
                        page_data['application_urls']].get_configs()
                    self.fields['application_configs'].widget.choices = [
                        (config.pk, force_text(config)) for config in configs
                    ]

                    try:
                        config = configs.get(
                            namespace=self.initial['application_namespace'])
                        self.fields['application_configs'].initial = config.pk
                    except ObjectDoesNotExist:
                        # Provided apphook configuration doesn't exist (anymore),
                        # just skip it
                        # The user will choose another value anyway
                        pass

        if 'redirect' in self.fields:
            self.fields['redirect'].widget.language = self._language
            self.fields['redirect'].initial = self.title_obj.redirect

        if 'overwrite_url' in self.fields and self.title_obj.has_url_overwrite:
            self.fields['overwrite_url'].initial = self.title_obj.path

    def get_apphooks(self):
        for hook in apphook_pool.get_apphooks():
            yield (hook[0], apphook_pool.get_apphook(hook[0]))

    def get_apphooks_with_config(self):
        return {key: app for key, app in self.get_apphooks() if app.app_config}

    def get_navigation_extenders(self):
        return menu_pool.get_menus_by_attribute("cms_enabled", True)

    def _check_unique_namespace_instance(self, namespace):
        return Page.objects.drafts().on_site(
            self._site).filter(application_namespace=namespace).exclude(
                pk=self.instance.pk).exists()

    def clean(self):
        cleaned_data = super(AdvancedSettingsForm, self).clean()

        if self._errors:
            # Fail fast if there's errors in the form
            return cleaned_data

        # Language has been validated already
        # so we know it exists.
        language_name = get_language_object(
            self._language,
            site_id=self._site.pk,
        )['name']

        if not self.title_obj.slug:
            # This covers all cases where users try to edit
            # page advanced settings without setting a title slug
            # for page titles that already exist.
            message = _("Please set the %(language)s slug "
                        "before editing its advanced settings.")
            raise ValidationError(message % {'language': language_name})

        if 'reverse_id' in self.fields:
            reverse_id = cleaned_data['reverse_id']
            if reverse_id:
                lookup = Page.objects.drafts().on_site(
                    self._site).filter(reverse_id=reverse_id)
                if lookup.exclude(pk=self.instance.pk).exists():
                    self._errors['reverse_id'] = self.error_class(
                        [_('A page with this reverse URL id exists already.')])
        apphook = cleaned_data.get('application_urls', None)
        # The field 'application_namespace' is a misnomer. It should be
        # 'instance_namespace'.
        instance_namespace = cleaned_data.get('application_namespace', None)
        application_config = cleaned_data.get('application_configs', None)
        if apphook:
            apphooks_with_config = self.get_apphooks_with_config()

            # application_config wins over application_namespace
            if apphook in apphooks_with_config and application_config:
                # the value of the application config namespace is saved in
                # the 'usual' namespace field to be backward compatible
                # with existing apphooks
                try:
                    appconfig_pk = forms.IntegerField(
                        required=True).to_python(application_config)
                except ValidationError:
                    self._errors['application_configs'] = ErrorList(
                        [_('Invalid application config value')])
                    return self.cleaned_data

                try:
                    config = apphooks_with_config[apphook].get_configs().get(
                        pk=appconfig_pk)
                except ObjectDoesNotExist:
                    self._errors['application_configs'] = ErrorList(
                        [_('Invalid application config value')])
                    return self.cleaned_data

                if self._check_unique_namespace_instance(config.namespace):
                    # Looks like there's already one with the default instance
                    # namespace defined.
                    self._errors['application_configs'] = ErrorList([
                        _('An application instance using this configuration already exists.'
                          )
                    ])
                else:
                    self.cleaned_data[
                        'application_namespace'] = config.namespace
            else:
                if instance_namespace:
                    if self._check_unique_namespace_instance(
                            instance_namespace):
                        self._errors['application_namespace'] = ErrorList([
                            _('An application instance with this name already exists.'
                              )
                        ])
                else:
                    # The attribute on the apps 'app_name' is a misnomer, it should be
                    # 'application_namespace'.
                    application_namespace = apphook_pool.get_apphook(
                        apphook).app_name
                    if application_namespace and not instance_namespace:
                        if self._check_unique_namespace_instance(
                                application_namespace):
                            # Looks like there's already one with the default instance
                            # namespace defined.
                            self._errors['application_namespace'] = ErrorList([
                                _('An application instance with this name already exists.'
                                  )
                            ])
                        else:
                            # OK, there are zero instances of THIS app that use the
                            # default instance namespace, so, since the user didn't
                            # provide one, we'll use the default. NOTE: The following
                            # line is really setting the "instance namespace" of the
                            # new app to the app’s "application namespace", which is
                            # the default instance namespace.
                            self.cleaned_data[
                                'application_namespace'] = application_namespace

        if instance_namespace and not apphook:
            self.cleaned_data['application_namespace'] = None

        if application_config and not apphook:
            self.cleaned_data['application_configs'] = None
        return self.cleaned_data

    def clean_xframe_options(self):
        if 'xframe_options' not in self.fields:
            return  # nothing to do, field isn't present

        xframe_options = self.cleaned_data['xframe_options']
        if xframe_options == '':
            return Page._meta.get_field('xframe_options').default

        return xframe_options

    def clean_overwrite_url(self):
        path_override = self.cleaned_data.get('overwrite_url')

        if path_override:
            path = path_override.strip('/')
        else:
            path = self.instance.get_path_for_slug(self.title_obj.slug,
                                                   self._language)

        validate_url_uniqueness(
            self._site,
            path=path,
            language=self._language,
            exclude_page=self.instance,
        )
        self.cleaned_data['path'] = path
        return path_override

    def has_changed_apphooks(self):
        changed_data = self.changed_data

        if 'application_urls' in changed_data:
            return True
        return 'application_namespace' in changed_data

    def update_apphooks(self):
        # User has changed the apphooks on the page.
        # Update the public version of the page to reflect this change immediately.
        public_id = self.instance.publisher_public_id
        self._meta.model.objects.filter(pk=public_id).update(
            application_urls=self.instance.application_urls,
            application_namespace=(self.instance.application_namespace
                                   or None),
        )

        # Connects the apphook restart handler to the request finished signal
        set_restart_trigger()

    def save(self, *args, **kwargs):
        data = self.cleaned_data
        page = super(AdvancedSettingsForm, self).save(*args, **kwargs)
        page.update_translations(
            self._language,
            path=data['path'],
            redirect=(data.get('redirect') or None),
            publisher_state=PUBLISHER_STATE_DIRTY,
            has_url_overwrite=bool(data.get('overwrite_url')),
        )
        is_draft_and_has_public = page.publisher_is_draft and page.publisher_public_id

        if is_draft_and_has_public and self.has_changed_apphooks():
            self.update_apphooks()
        page.clear_cache(menu=True)
        return page
Beispiel #2
0
class AdvancedSettingsForm(forms.ModelForm):
    from cms.forms.fields import PageSmartLinkField
    application_urls = forms.ChoiceField(label=_('Application'),
                                         choices=(), required=False,
                                         help_text=_('Hook application to this page.'))
    overwrite_url = forms.CharField(label=_('Overwrite URL'), max_length=255, required=False,
                                    help_text=_('Keep this field empty if standard path should be used.'))

    xframe_options = forms.ChoiceField(
        choices=Page._meta.get_field('xframe_options').choices,
        label=_('X Frame Options'),
        help_text=_('Whether this page can be embedded in other pages or websites'),
        initial=Page._meta.get_field('xframe_options').default,
        required=False
    )

    redirect = PageSmartLinkField(label=_('Redirect'), required=False,
                    help_text=_('Redirects to this URL.'), placeholder_text=_('Start typing...'),
                    ajax_view='admin:cms_page_get_published_pagelist'
    )

    language = forms.ChoiceField(label=_("Language"), choices=get_language_tuple(),
                                 help_text=_('The current language of the content fields.'))

    fieldsets = (
        (None, {
            'fields': ('overwrite_url','redirect'),
        }),
        ('Language independent options', {
            'fields': ('site', 'template', 'reverse_id', 'soft_root', 'navigation_extenders',
            'application_urls', 'application_namespace', "xframe_options",)
        })
    )

    def __init__(self, *args, **kwargs):
        super(AdvancedSettingsForm, self).__init__(*args, **kwargs)
        self.fields['language'].widget = HiddenInput()
        self.fields['site'].widget = HiddenInput()
        site_id = self.fields['site'].initial

        languages = get_language_tuple(site_id)
        self.fields['language'].choices = languages
        if not self.fields['language'].initial:
            self.fields['language'].initial = get_language()
        if 'navigation_extenders' in self.fields:
            self.fields['navigation_extenders'].widget = forms.Select({},
                [('', "---------")] + menu_pool.get_menus_by_attribute("cms_enabled", True))
        if 'application_urls' in self.fields:
            # Prepare a dict mapping the apps by class name ('PollApp') to
            # their app_name attribute ('polls'), if any.
            app_namespaces = {}
            for hook in apphook_pool.get_apphooks():
                app = apphook_pool.get_apphook(hook[0])
                if app.app_name:
                    app_namespaces[hook[0]] = app.app_name

            self.fields['application_urls'].widget = AppHookSelect(
                attrs={'id':'application_urls'},
                app_namespaces=app_namespaces,
            )
            self.fields['application_urls'].choices = [('', "---------")] + apphook_pool.get_apphooks()

        if 'redirect' in self.fields:
            self.fields['redirect'].widget.language = self.fields['language'].initial

    def clean(self):
        cleaned_data = super(AdvancedSettingsForm, self).clean()
        if 'reverse_id' in self.fields:
            id = cleaned_data['reverse_id']
            site_id = cleaned_data['site']
            if id:
                if Page.objects.filter(reverse_id=id, site=site_id, publisher_is_draft=True).exclude(
                        pk=self.instance.pk).count():
                    self._errors['reverse_id'] = self.error_class(
                        [_('A page with this reverse URL id exists already.')])
        apphook = cleaned_data.get('application_urls', None)
        # The field 'application_namespace' is a misnomer. It should be
        # 'instance_namespace'.
        instance_namespace = cleaned_data.get('application_namespace', None)
        if apphook:
            # The attribute on the apps 'app_name' is a misnomer, it should be
            # 'application_namespace'.
            application_namespace = apphook_pool.get_apphook(apphook).app_name
            if application_namespace and not instance_namespace:
                if Page.objects.filter(
                    publisher_is_draft=True,
                    application_urls=apphook,
                    application_namespace=application_namespace
                ).exclude(pk=self.instance.pk).count():
                    # Looks like there's already one with the default instance
                    # namespace defined.
                    self._errors['application_urls'] = ErrorList([
                        _('''You selected an apphook with an "app_name".
                            You must enter a unique instance name.''')
                    ])
                else:
                    # OK, there are zero instances of THIS app that use the
                    # default instance namespace, so, since the user didn't
                    # provide one, we'll use the default. NOTE: The following
                    # line is really setting the "instance namespace" of the
                    # new app to the app’s "application namespace", which is
                    # the default instance namespace.
                    self.cleaned_data['application_namespace'] = application_namespace

        if instance_namespace and not apphook:
            self.cleaned_data['application_namespace'] = None

        return cleaned_data

    def clean_application_namespace(self):
        namespace = self.cleaned_data['application_namespace']
        if namespace and Page.objects.filter(publisher_is_draft=True, application_namespace=namespace).exclude(pk=self.instance.pk).count():
            raise ValidationError(_('A instance name with this name already exists.'))
        return namespace

    def clean_xframe_options(self):
        if 'xframe_options' not in self.fields:
            return # nothing to do, field isn't present

        xframe_options = self.cleaned_data['xframe_options']
        if xframe_options == '':
            return Page._meta.get_field('xframe_options').default

        return xframe_options

    def clean_overwrite_url(self):
        if 'overwrite_url' in self.fields:
            url = self.cleaned_data['overwrite_url']
            is_valid_url(url, self.instance)
            return url

    class Meta:
        model = Page
        fields = [
            'site', 'template', 'reverse_id', 'overwrite_url', 'redirect', 'soft_root', 'navigation_extenders',
            'application_urls', 'application_namespace', "xframe_options",
        ]
Beispiel #3
0
class AdvancedSettingsForm(forms.ModelForm):
    from cms.forms.fields import PageSmartLinkField
    application_urls = forms.ChoiceField(
        label=_('Application'),
        choices=(),
        required=False,
        help_text=_('Hook application to this page.'))
    overwrite_url = forms.CharField(
        label=_('Overwrite URL'),
        max_length=255,
        required=False,
        help_text=_('Keep this field empty if standard path should be used.'))

    xframe_options = forms.ChoiceField(
        choices=Page._meta.get_field('xframe_options').choices,
        label=_('X Frame Options'),
        help_text=_(
            'Whether this page can be embedded in other pages or websites'),
        initial=Page._meta.get_field('xframe_options').default,
        required=False)

    redirect = PageSmartLinkField(
        label=_('Redirect'),
        required=False,
        help_text=_('Redirects to this URL.'),
        placeholder_text=_('Start typing...'),
        ajax_view='admin:cms_page_get_published_pagelist')

    language = forms.ChoiceField(
        label=_("Language"),
        choices=get_language_tuple(),
        help_text=_('The current language of the content fields.'))

    # This is really a 'fake' field which does not correspond to any Page attribute
    # But creates a stub field to be populate by js
    application_configs = forms.ChoiceField(
        label=_('Application configurations'),
        choices=(),
        required=False,
    )
    fieldsets = ((None, {
        'fields': ('overwrite_url', 'redirect'),
    }), (_('Language independent options'), {
        'fields': (
            'site',
            'template',
            'reverse_id',
            'soft_root',
            'navigation_extenders',
            'application_urls',
            'application_namespace',
            'application_configs',
            'xframe_options',
        )
    }))

    def __init__(self, *args, **kwargs):
        super(AdvancedSettingsForm, self).__init__(*args, **kwargs)
        self.fields['language'].widget = HiddenInput()
        self.fields['site'].widget = HiddenInput()
        site_id = self.fields['site'].initial

        languages = get_language_tuple(site_id)
        self.fields['language'].choices = languages
        if not self.fields['language'].initial:
            self.fields['language'].initial = get_language()
        if 'navigation_extenders' in self.fields:
            navigation_extenders = self.get_navigation_extenders()
            self.fields['navigation_extenders'].widget = forms.Select(
                {}, [('', "---------")] + navigation_extenders)
        if 'application_urls' in self.fields:
            # Prepare a dict mapping the apps by class name ('PollApp') to
            # their app_name attribute ('polls'), if any.
            app_namespaces = {}
            app_configs = {}
            for hook in apphook_pool.get_apphooks():
                app = apphook_pool.get_apphook(hook[0])
                if app.app_name:
                    app_namespaces[hook[0]] = app.app_name
                if app.app_config:
                    app_configs[hook[0]] = app

            self.fields['application_urls'].widget = AppHookSelect(
                attrs={'id': 'application_urls'},
                app_namespaces=app_namespaces)
            self.fields['application_urls'].choices = [
                ('', "---------")
            ] + apphook_pool.get_apphooks()

            page_data = self.data if self.data else self.initial
            if app_configs:
                self.fields[
                    'application_configs'].widget = ApplicationConfigSelect(
                        attrs={'id': 'application_configs'},
                        app_configs=app_configs)

                if page_data.get(
                        'application_urls', False
                ) and page_data['application_urls'] in app_configs:
                    self.fields['application_configs'].choices = [
                        (config.pk, force_text(config))
                        for config in app_configs[
                            page_data['application_urls']].get_configs()
                    ]

                    apphook = page_data.get('application_urls', False)
                    try:
                        config = apphook_pool.get_apphook(apphook).get_configs(
                        ).get(namespace=self.initial['application_namespace'])
                        self.fields['application_configs'].initial = config.pk
                    except ObjectDoesNotExist:
                        # Provided apphook configuration doesn't exist (anymore),
                        # just skip it
                        # The user will choose another value anyway
                        pass
                else:
                    # If app_config apphook is not selected, drop any value
                    # for application_configs to avoid the field data from
                    # being validated by the field itself
                    try:
                        del self.data['application_configs']
                    except KeyError:
                        pass

        if 'redirect' in self.fields:
            self.fields['redirect'].widget.language = self.fields[
                'language'].initial

    def get_navigation_extenders(self):
        return menu_pool.get_menus_by_attribute("cms_enabled", True)

    def _check_unique_namespace_instance(self, namespace):
        return Page.objects.filter(publisher_is_draft=True,
                                   application_namespace=namespace).exclude(
                                       pk=self.instance.pk).exists()

    def clean(self):
        cleaned_data = super(AdvancedSettingsForm, self).clean()

        if self._errors:
            # Fail fast if there's errors in the form
            return cleaned_data

        language = cleaned_data['language']
        # Language has been validated already
        # so we know it exists.
        language_name = get_language_object(
            language, site_id=cleaned_data['site'].pk)['name']

        try:
            title = self.instance.title_set.get(language=language)
        except Title.DoesNotExist:
            # This covers all cases where users try to edit
            # page advanced settings without creating the page title.
            message = _("Please create the %(language)s page "
                        "translation before editing its advanced settings.")
            raise ValidationError(message % {'language': language_name})

        if not title.slug:
            # This covers all cases where users try to edit
            # page advanced settings without setting a title slug
            # for page titles that already exist.
            message = _("Please set the %(language)s slug "
                        "before editing its advanced settings.")
            raise ValidationError(message % {'language': language_name})

        if 'reverse_id' in self.fields:
            id = cleaned_data['reverse_id']
            site_id = cleaned_data['site']
            if id:
                if Page.objects.filter(reverse_id=id,
                                       site=site_id,
                                       publisher_is_draft=True).exclude(
                                           pk=self.instance.pk).exists():
                    self._errors['reverse_id'] = self.error_class(
                        [_('A page with this reverse URL id exists already.')])
        apphook = cleaned_data.get('application_urls', None)
        # The field 'application_namespace' is a misnomer. It should be
        # 'instance_namespace'.
        instance_namespace = cleaned_data.get('application_namespace', None)
        application_config = cleaned_data.get('application_configs', None)
        if apphook:
            # application_config wins over application_namespace
            if application_config:
                # the value of the application config namespace is saved in
                # the 'usual' namespace field to be backward compatible
                # with existing apphooks
                config = apphook_pool.get_apphook(apphook).get_configs().get(
                    pk=int(application_config))
                if self._check_unique_namespace_instance(config.namespace):
                    # Looks like there's already one with the default instance
                    # namespace defined.
                    self._errors['application_configs'] = ErrorList([
                        _('An application instance using this configuration already exists.'
                          )
                    ])
                else:
                    self.cleaned_data[
                        'application_namespace'] = config.namespace
            else:
                if instance_namespace:
                    if self._check_unique_namespace_instance(
                            instance_namespace):
                        self._errors['application_namespace'] = ErrorList([
                            _('An application instance with this name already exists.'
                              )
                        ])
                else:
                    # The attribute on the apps 'app_name' is a misnomer, it should be
                    # 'application_namespace'.
                    application_namespace = apphook_pool.get_apphook(
                        apphook).app_name
                    if application_namespace and not instance_namespace:
                        if self._check_unique_namespace_instance(
                                application_namespace):
                            # Looks like there's already one with the default instance
                            # namespace defined.
                            self._errors['application_namespace'] = ErrorList([
                                _('An application instance with this name already exists.'
                                  )
                            ])
                        else:
                            # OK, there are zero instances of THIS app that use the
                            # default instance namespace, so, since the user didn't
                            # provide one, we'll use the default. NOTE: The following
                            # line is really setting the "instance namespace" of the
                            # new app to the app’s "application namespace", which is
                            # the default instance namespace.
                            self.cleaned_data[
                                'application_namespace'] = application_namespace

        if instance_namespace and not apphook:
            self.cleaned_data['application_namespace'] = None

        if application_config and not apphook:
            self.cleaned_data['application_configs'] = None

        return self.cleaned_data

    def clean_xframe_options(self):
        if 'xframe_options' not in self.fields:
            return  # nothing to do, field isn't present

        xframe_options = self.cleaned_data['xframe_options']
        if xframe_options == '':
            return Page._meta.get_field('xframe_options').default

        return xframe_options

    def clean_overwrite_url(self):
        if 'overwrite_url' in self.fields:
            url = self.cleaned_data['overwrite_url']
            is_valid_url(url, self.instance)
            return url

    class Meta:
        model = Page
        fields = [
            'site',
            'template',
            'reverse_id',
            'overwrite_url',
            'redirect',
            'soft_root',
            'navigation_extenders',
            'application_urls',
            'application_namespace',
            "xframe_options",
        ]
Beispiel #4
0
class AdvancedSettingsForm(forms.ModelForm):
    from cms.forms.fields import PageSmartLinkField
    application_urls = forms.ChoiceField(
        label=_('Application'),
        choices=(),
        required=False,
        help_text=_('Hook application to this page.'))
    overwrite_url = forms.CharField(
        label=_('Overwrite URL'),
        max_length=255,
        required=False,
        help_text=_('Keep this field empty if standard path should be used.'))

    xframe_options = forms.ChoiceField(
        choices=Page._meta.get_field('xframe_options').choices,
        label=_('X Frame Options'),
        help_text=_(
            'Whether this page can be embedded in other pages or websites'),
        initial=Page._meta.get_field('xframe_options').default,
        required=False)

    redirect = PageSmartLinkField(label=_('Redirect'),
                                  required=False,
                                  help_text=_('Redirects to this URL.'),
                                  placeholder_text=_('Start typing...'))

    language = forms.ChoiceField(
        label=_("Language"),
        choices=get_language_tuple(),
        help_text=_('The current language of the content fields.'))

    def __init__(self, *args, **kwargs):
        super(AdvancedSettingsForm, self).__init__(*args, **kwargs)
        self.fields['language'].widget = HiddenInput()
        self.fields['site'].widget = HiddenInput()
        site_id = self.fields['site'].initial

        languages = get_language_tuple(site_id)
        self.fields['language'].choices = languages
        if not self.fields['language'].initial:
            self.fields['language'].initial = get_language()
        if 'navigation_extenders' in self.fields:
            self.fields['navigation_extenders'].widget = forms.Select(
                {}, [('', "---------")] +
                menu_pool.get_menus_by_attribute("cms_enabled", True))
        if 'application_urls' in self.fields:
            self.fields['application_urls'].choices = [
                ('', "---------")
            ] + apphook_pool.get_apphooks()

        if 'redirect' in self.fields:
            self.fields['redirect'].widget.language = self.fields[
                'language'].initial

    def clean(self):
        cleaned_data = super(AdvancedSettingsForm, self).clean()
        if 'reverse_id' in self.fields:
            id = cleaned_data['reverse_id']
            site_id = cleaned_data['site']
            if id:
                if Page.objects.filter(reverse_id=id,
                                       site=site_id,
                                       publisher_is_draft=True).exclude(
                                           pk=self.instance.pk).count():
                    self._errors['reverse_id'] = self.error_class(
                        [_('A page with this reverse URL id exists already.')])
        apphook = cleaned_data.get('application_urls', None)
        namespace = cleaned_data.get('application_namespace', None)
        if apphook:
            apphook_pool.discover_apps()
            if apphook_pool.apps[apphook].app_name and not namespace:
                self._errors['application_urls'] = ErrorList([
                    _('You selected an apphook with an "app_name". You must enter a instance name.'
                      )
                ])
        if namespace and not apphook:
            self._errors['application_namespace'] = ErrorList([
                _("If you enter an instance name you need an application url as well."
                  )
            ])
        return cleaned_data

    def clean_application_namespace(self):
        namespace = self.cleaned_data['application_namespace']
        if namespace and Page.objects.filter(
                publisher_is_draft=True,
                application_namespace=namespace).exclude(
                    pk=self.instance.pk).count():
            raise ValidationError(
                _('A instance name with this name already exists.'))
        return namespace

    def clean_xframe_options(self):
        if 'xframe_options' not in self.fields:
            return  # nothing to do, field isn't present

        xframe_options = self.cleaned_data['xframe_options']
        if xframe_options == '':
            return Page._meta.get_field('xframe_options').default

        return xframe_options

    def clean_overwrite_url(self):
        if 'overwrite_url' in self.fields:
            url = self.cleaned_data['overwrite_url']
            is_valid_url(url, self.instance)
            return url

    class Meta:
        model = Page
        fields = [
            'site',
            'template',
            'reverse_id',
            'overwrite_url',
            'redirect',
            'soft_root',
            'navigation_extenders',
            'application_urls',
            'application_namespace',
            "xframe_options",
        ]