Пример #1
0
class PageAdmin(item_editor.ItemEditor, tree_editor.TreeEditor):
    class Media:
        css = {}
        js = []

    form = PageAdminForm

    # the fieldsets config here is used for the add_view, it has no effect
    # for the change_view which is completely customized anyway
    unknown_fields = ['template_key', 'parent', 'override_url', 'redirect_to']
    fieldset_insertion_index = 2
    fieldsets = [
        (None, {
            'fields': [
                ('title', 'slug'),
                ('active', 'in_navigation'),
                ],
        }),
        (_('Other options'), {
            'classes': ['collapse',],
            'fields': unknown_fields,
        }),
        # <-- insertion point, extensions appear here, see insertion_index above
        item_editor.FEINCMS_CONTENT_FIELDSET,
        ]
    readonly_fields = []
    list_display = ['short_title', 'is_visible_admin', 'in_navigation_toggle', 'template']
    list_filter = ['active', 'in_navigation', 'template_key', 'parent']
    search_fields = ['title', 'slug']
    prepopulated_fields = { 'slug': ('title',), }

    raw_id_fields = ['parent']
    radio_fields = {'template_key': admin.HORIZONTAL}

    @classmethod
    def add_extension_options(cls, *f):
        if isinstance(f[-1], dict):     # called with a fieldset
            cls.fieldsets.insert(cls.fieldset_insertion_index, f)
            f[1]['classes'] = list(f[1].get('classes', []))
            f[1]['classes'].append('collapse')
        else:   # assume called with "other" fields
            cls.fieldsets[1][1]['fields'].extend(f)

    def __init__(self, *args, **kwargs):
        ensure_completely_loaded()

        if len(Page._feincms_templates) > 4 and 'template_key' in self.radio_fields:
            del(self.radio_fields['template_key'])

        super(PageAdmin, self).__init__(*args, **kwargs)

        # The use of fieldsets makes only fields explicitly listed in there
        # actually appear in the admin form. However, extensions should not be
        # aware that there is a fieldsets structure and even less modify it;
        # we therefore enumerate all of the model's field and forcibly add them
        # to the last section in the admin. That way, nobody is left behind.
        from django.contrib.admin.util import flatten_fieldsets
        present_fields = flatten_fieldsets(self.fieldsets)

        for f in self.model._meta.fields:
            if not f.name.startswith('_') and not f.name in ('id', 'lft', 'rght', 'tree_id', 'level') and \
                    not f.auto_created and not f.name in present_fields and f.editable:
                self.unknown_fields.append(f.name)
            if not f.editable:
                self.readonly_fields.append(f.name)

    in_navigation_toggle = tree_editor.ajax_editable_boolean('in_navigation', _('in navigation'))

    def _actions_column(self, page):
        editable = getattr(page, 'feincms_editable', True)

        preview_url = "../../r/%s/%s/" % (
                ContentType.objects.get_for_model(self.model).id,
                page.id)
        actions = super(PageAdmin, self)._actions_column(page)
        if editable:
            actions.insert(0, u'<a href="add/?parent=%s" title="%s"><img src="%sfeincms/img/icon_addlink.gif" alt="%s"></a>' % (
                page.pk, _('Add child page'), django_settings.STATIC_URL, _('Add child page')))
        actions.insert(0, u'<a href="%s" title="%s"><img src="%sfeincms/img/selector-search.gif" alt="%s" /></a>' % (
            preview_url, _('View on site'), django_settings.STATIC_URL, _('View on site')))

        return actions

    def add_view(self, request, **kwargs):
        # Preserve GET parameters
        kwargs['form_url'] = request.get_full_path()
        return super(PageAdmin, self).add_view(request, **kwargs)

    def response_add(self, request, obj, *args, **kwargs):
        response = super(PageAdmin, self).response_add(request, obj, *args, **kwargs)
        if 'parent' in request.GET and '_addanother' in request.POST and response.status_code in (301, 302):
            # Preserve GET parameters if we are about to add another page
            response['Location'] += '?parent=%s' % request.GET['parent']
        if 'translation_of' in request.GET:
            # Copy all contents
            for content_type in obj._feincms_content_types:
                if content_type.objects.filter(parent=obj).exists():
                    # Short-circuit processing -- don't copy any contents if
                    # newly added object already has some
                    return response

            try:
                original = self.model._tree_manager.get(pk=request.GET.get('translation_of'))
                original = original.original_translation
                obj.copy_content_from(original)
                obj.save()

                self.message_user(request, _('The content from the original translation has been copied to the newly created page.'))
            except (AttributeError, self.model.DoesNotExist):
                pass

        return response

    def _refresh_changelist_caches(self, *args, **kwargs):
        self._visible_pages = list(self.model.objects.active().values_list('id', flat=True))

    def change_view(self, request, object_id, **kwargs):
        try:
            return super(PageAdmin, self).change_view(request, object_id, **kwargs)
        except PermissionDenied:
            from django.contrib import messages
            messages.add_message(request, messages.ERROR, _("You don't have the necessary permissions to edit this object"))
        return HttpResponseRedirect(reverse('admin:page_page_changelist'))

    def is_visible_admin(self, page):
        """
        Instead of just showing an on/off boolean, also indicate whether this
        page is not visible because of publishing dates or inherited status.
        """
        if not hasattr(self, "_visible_pages"):
            self._visible_pages = list() # Sanity check in case this is not already defined

        if page.parent_id and not page.parent_id in self._visible_pages:
            # parent page's invisibility is inherited
            if page.id in self._visible_pages:
                self._visible_pages.remove(page.id)
            return tree_editor.ajax_editable_boolean_cell(page, 'active', override=False, text=_('inherited'))

        if page.active and not page.id in self._visible_pages:
            # is active but should not be shown, so visibility limited by extension: show a "not active"
            return tree_editor.ajax_editable_boolean_cell(page, 'active', override=False, text=_('extensions'))

        return tree_editor.ajax_editable_boolean_cell(page, 'active')
    is_visible_admin.allow_tags = True
    is_visible_admin.short_description = _('is active')
    is_visible_admin.editable_boolean_field = 'active'

    # active toggle needs more sophisticated result function
    def is_visible_recursive(self, page):
        retval = []
        for c in page.get_descendants(include_self=True):
            retval.append(self.is_visible_admin(c))
        return retval
    is_visible_admin.editable_boolean_result = is_visible_recursive
Пример #2
0
class PageAdmin(item_editor.ItemEditor, tree_editor.TreeEditor):
    class Media:
        css = {}
        js = []

    form = PageAdminForm

    fieldset_insertion_index = 2
    fieldsets = [
        (None, {
            "fields": [("title", "slug"), ("active", "in_navigation")]
        }),
        (
            _("Other options"),
            {
                "classes": ["collapse"],
                "fields":
                ["template_key", "parent", "override_url", "redirect_to"],
            },
        ),
        # <-- insertion point, extensions appear here, see insertion_index
        # above
        item_editor.FEINCMS_CONTENT_FIELDSET,
    ]
    readonly_fields = []
    list_display = [
        "short_title",
        "is_visible_admin",
        "in_navigation_toggle",
        "template",
    ]
    list_filter = ["active", "in_navigation", "template_key", "parent"]
    search_fields = ["title", "slug"]
    prepopulated_fields = {"slug": ("title", )}

    raw_id_fields = ["parent"]
    radio_fields = {"template_key": admin.HORIZONTAL}

    @classmethod
    def add_extension_options(cls, *f):
        if isinstance(f[-1], dict):  # called with a fieldset
            cls.fieldsets.insert(cls.fieldset_insertion_index, f)
            f[1]["classes"] = list(f[1].get("classes", []))
            f[1]["classes"].append("collapse")
        else:  # assume called with "other" fields
            cls.fieldsets[1][1]["fields"].extend(f)

    def __init__(self, model, admin_site):
        ensure_completely_loaded()

        if len(model._feincms_templates
               ) > 4 and "template_key" in self.radio_fields:
            del self.radio_fields["template_key"]

        super(PageAdmin, self).__init__(model, admin_site)

    in_navigation_toggle = tree_editor.ajax_editable_boolean(
        "in_navigation", _("in navigation"))

    def get_readonly_fields(self, request, obj=None):
        readonly = super(PageAdmin, self).get_readonly_fields(request, obj=obj)
        if (not settings.FEINCMS_SINGLETON_TEMPLATE_CHANGE_ALLOWED and obj
                and obj.template and obj.template.singleton):
            return tuple(readonly) + ("template_key", )
        return readonly

    def get_form(self, *args, **kwargs):
        form = super(PageAdmin, self).get_form(*args, **kwargs)
        return partial(form, modeladmin=self)

    def _actions_column(self, page):
        addable = getattr(page, "feincms_addable", True)

        preview_url = "../../r/%s/%s/" % (
            ContentType.objects.get_for_model(self.model).id,
            page.id,
        )
        actions = super(PageAdmin, self)._actions_column(page)

        if addable and not page.template.enforce_leaf:
            actions.insert(
                0,
                '<a href="add/?parent=%s" title="%s">'
                '<img src="%s" alt="%s" />'
                "</a>" % (
                    page.pk,
                    _("Add child page"),
                    static("feincms/img/icon_addlink.gif"),
                    _("Add child page"),
                ),
            )
        actions.insert(
            0,
            '<a href="%s" title="%s">'
            '<img src="%s" alt="%s" />'
            "</a>" % (
                preview_url,
                _("View on site"),
                static("feincms/img/selector-search.gif"),
                _("View on site"),
            ),
        )
        return actions

    def add_view(self, request, **kwargs):
        kwargs["form_url"] = request.get_full_path()  # Preserve GET parameters
        if "translation_of" in request.GET and "language" in request.GET:
            try:
                original = self.model._tree_manager.get(
                    pk=request.GET.get("translation_of"))
            except (AttributeError, self.model.DoesNotExist):
                pass
            else:
                language_code = request.GET["language"]
                language = dict(django_settings.LANGUAGES).get(
                    language_code, "")
                kwargs["extra_context"] = {
                    "adding_translation": True,
                    "title":
                    _('Add %(language)s translation of "%(page)s"') % {
                        "language": language,
                        "page": original
                    },
                    "language_name": language,
                    "translation_of": original,
                }
        return super(PageAdmin, self).add_view(request, **kwargs)

    def response_add(self, request, obj, *args, **kwargs):
        response = super(PageAdmin, self).response_add(request, obj, *args,
                                                       **kwargs)
        if ("parent" in request.GET and "_addanother" in request.POST
                and response.status_code in (301, 302)):
            # Preserve GET parameters if we are about to add another page
            response["Location"] += "?parent=%s" % request.GET["parent"]

        if ("translation_of" in request.GET
                and "_copy_content_from_original" in request.POST):
            # Copy all contents
            for content_type in obj._feincms_content_types:
                if content_type.objects.filter(parent=obj).exists():
                    # Short-circuit processing -- don't copy any contents if
                    # newly added object already has some
                    return response

            try:
                original = self.model._tree_manager.get(
                    pk=request.GET.get("translation_of"))
                original = original.original_translation
                obj.copy_content_from(original)
                obj.save()

                self.message_user(
                    request,
                    _("The content from the original translation has been copied"
                      " to the newly created page."),
                )
            except (AttributeError, self.model.DoesNotExist):
                pass

        return response

    def change_view(self, request, object_id, **kwargs):
        try:
            return super(PageAdmin, self).change_view(request, object_id,
                                                      **kwargs)
        except PermissionDenied:
            messages.add_message(
                request,
                messages.ERROR,
                _("You don't have the necessary permissions to edit this"
                  " object"),
            )
        return HttpResponseRedirect(reverse("admin:page_page_changelist"))

    def has_delete_permission(self, request, obj=None):
        if (not settings.FEINCMS_SINGLETON_TEMPLATE_DELETION_ALLOWED and obj
                and obj.template.singleton):
            return False
        return super(PageAdmin, self).has_delete_permission(request, obj=obj)

    def changelist_view(self, request, *args, **kwargs):
        _local.visible_pages = list(self.model.objects.active().values_list(
            "id", flat=True))
        return super(PageAdmin, self).changelist_view(request, *args, **kwargs)

    def is_visible_admin(self, page):
        """
        Instead of just showing an on/off boolean, also indicate whether this
        page is not visible because of publishing dates or inherited status.
        """
        if page.parent_id and page.parent_id not in _local.visible_pages:
            # parent page's invisibility is inherited
            if page.id in _local.visible_pages:
                _local.visible_pages.remove(page.id)
            return tree_editor.ajax_editable_boolean_cell(page,
                                                          "active",
                                                          override=False,
                                                          text=_("inherited"))

        if page.active and page.id not in _local.visible_pages:
            # is active but should not be shown, so visibility limited by
            # extension: show a "not active"
            return tree_editor.ajax_editable_boolean_cell(page,
                                                          "active",
                                                          override=False,
                                                          text=_("extensions"))

        return tree_editor.ajax_editable_boolean_cell(page, "active")

    is_visible_admin.short_description = _("is active")
    is_visible_admin.editable_boolean_field = "active"

    # active toggle needs more sophisticated result function
    def is_visible_recursive(self, page):
        # Have to refresh visible_pages here, because TreeEditor.toggle_boolean
        # will have changed the value when inside this code path.
        _local.visible_pages = list(self.model.objects.active().values_list(
            "id", flat=True))

        return [
            self.is_visible_admin(c)
            for c in page.get_descendants(include_self=True)
        ]

    is_visible_admin.editable_boolean_result = is_visible_recursive
 def handle_modeladmin(self, modeladmin):
     setattr(type(modeladmin), 'in_footer_toggle',
             tree_editor.ajax_editable_boolean('in_footer', _('in footer')))
     modeladmin.list_display.insert(3, 'in_footer_toggle')
Пример #4
0
def register(cls, admin_cls):
    cls.add_to_class('in_footer', models.BooleanField(_('In footer'), default=False,
        help_text=_('This displays the page in the footer navigation.')))

    setattr(admin_cls, 'in_footer_toggle', tree_editor.ajax_editable_boolean('in_footer', _('in footer')))
    admin_cls.list_display.insert(3, 'in_footer_toggle')
Пример #5
0
from feincms.module.page.admin import PageAdmin
from feincms.module.page.models import Page
from guardian.admin import GuardedModelAdmin

from django.utils.translation import ugettext_lazy as _
from django.contrib import admin

PageAdmin.__bases__ = (GuardedModelAdmin,) + PageAdmin.__bases__
PageAdmin.fieldsets[0][1]["fields"][1] += (
    "require_login","require_permission", "only_public")
PageAdmin.change_form_template = "admin/page_editor.html"


from feincms.admin import tree_editor
PageAdmin.list_display[3:0] = ["require_login_toggle", "only_public_toggle"]
PageAdmin.list_filter.insert(2, "require_login")

PageAdmin.require_login_toggle = tree_editor.ajax_editable_boolean('require_login', _('require login'))
PageAdmin.only_public_toggle = tree_editor.ajax_editable_boolean('only_public', _('only public'))

admin.site.unregister(Page)
admin.site.register(Page, PageAdmin)

Пример #6
0
class PageAdmin(item_editor.ItemEditor, tree_editor.TreeEditor):
    class Media:
        css = {}
        js = []

    form = PageAdminForm

    fieldset_insertion_index = 2
    fieldsets = [
        (None, {
            'fields': [
                ('title', 'slug'),
                ('active', 'in_navigation'),
            ],
        }),
        (_('Other options'), {
            'classes': ['collapse'],
            'fields':
            ['template_key', 'parent', 'override_url', 'redirect_to'],
        }),
        # <-- insertion point, extensions appear here, see insertion_index
        # above
        item_editor.FEINCMS_CONTENT_FIELDSET,
    ]
    readonly_fields = []
    list_display = [
        'short_title', 'is_visible_admin', 'in_navigation_toggle', 'template'
    ]
    list_filter = ['active', 'in_navigation', 'template_key', 'parent']
    search_fields = ['title', 'slug']
    prepopulated_fields = {'slug': ('title', )}

    raw_id_fields = ['parent']
    radio_fields = {'template_key': admin.HORIZONTAL}

    @classmethod
    def add_extension_options(cls, *f):
        if isinstance(f[-1], dict):  # called with a fieldset
            cls.fieldsets.insert(cls.fieldset_insertion_index, f)
            f[1]['classes'] = list(f[1].get('classes', []))
            f[1]['classes'].append('collapse')
        else:  # assume called with "other" fields
            cls.fieldsets[1][1]['fields'].extend(f)

    def __init__(self, model, admin_site):
        ensure_completely_loaded()

        if len(model._feincms_templates) > 4 and \
                'template_key' in self.radio_fields:
            del (self.radio_fields['template_key'])

        super(PageAdmin, self).__init__(model, admin_site)

    in_navigation_toggle = tree_editor.ajax_editable_boolean(
        'in_navigation', _('in navigation'))

    def get_readonly_fields(self, request, obj=None):
        readonly = super(PageAdmin, self).get_readonly_fields(request, obj=obj)
        if not settings.FEINCMS_SINGLETON_TEMPLATE_CHANGE_ALLOWED:
            if obj and obj.template and obj.template.singleton:
                return tuple(readonly) + ('template_key', )
        return readonly

    def get_form(self, *args, **kwargs):
        form = super(PageAdmin, self).get_form(*args, **kwargs)
        return curry(form, modeladmin=self)

    def _actions_column(self, page):
        addable = getattr(page, 'feincms_addable', True)

        preview_url = "../../r/%s/%s/" % (ContentType.objects.get_for_model(
            self.model).id, page.id)
        actions = super(PageAdmin, self)._actions_column(page)

        if addable:
            if not page.template.enforce_leaf:
                actions.insert(
                    0, '<a href="add/?parent=%s" title="%s">'
                    '<img src="%s" alt="%s" />'
                    '</a>' % (
                        page.pk,
                        _('Add child page'),
                        static('feincms/img/icon_addlink.gif'),
                        _('Add child page'),
                    ))
        actions.insert(
            0, '<a href="%s" title="%s">'
            '<img src="%s" alt="%s" />'
            '</a>' % (
                preview_url,
                _('View on site'),
                static('feincms/img/selector-search.gif'),
                _('View on site'),
            ))
        return actions

    def add_view(self, request, **kwargs):
        kwargs['form_url'] = request.get_full_path()  # Preserve GET parameters
        if 'translation_of' in request.GET and 'language' in request.GET:
            try:
                original = self.model._tree_manager.get(
                    pk=request.GET.get('translation_of'))
            except (AttributeError, self.model.DoesNotExist):
                pass
            else:
                language_code = request.GET['language']
                language = dict(django_settings.LANGUAGES).get(
                    language_code, '')
                kwargs['extra_context'] = {
                    'adding_translation': True,
                    'title':
                    _('Add %(language)s translation of "%(page)s"') % {
                        'language': language,
                        'page': original,
                    },
                    'language_name': language,
                    'translation_of': original,
                }
        return super(PageAdmin, self).add_view(request, **kwargs)

    def response_add(self, request, obj, *args, **kwargs):
        response = super(PageAdmin, self).response_add(request, obj, *args,
                                                       **kwargs)
        if ('parent' in request.GET and '_addanother' in request.POST
                and response.status_code in (301, 302)):
            # Preserve GET parameters if we are about to add another page
            response['Location'] += '?parent=%s' % request.GET['parent']

        if ('translation_of' in request.GET
                and '_copy_content_from_original' in request.POST):
            # Copy all contents
            for content_type in obj._feincms_content_types:
                if content_type.objects.filter(parent=obj).exists():
                    # Short-circuit processing -- don't copy any contents if
                    # newly added object already has some
                    return response

            try:
                original = self.model._tree_manager.get(
                    pk=request.GET.get('translation_of'))
                original = original.original_translation
                obj.copy_content_from(original)
                obj.save()

                self.message_user(
                    request,
                    _('The content from the original translation has been copied'
                      ' to the newly created page.'))
            except (AttributeError, self.model.DoesNotExist):
                pass

        return response

    def _refresh_changelist_caches(self, *args, **kwargs):
        self._visible_pages = list(self.model.objects.active().values_list(
            'id', flat=True))

    def change_view(self, request, object_id, **kwargs):
        try:
            return super(PageAdmin, self).change_view(request, object_id,
                                                      **kwargs)
        except PermissionDenied:
            messages.add_message(
                request, messages.ERROR,
                _("You don't have the necessary permissions to edit this"
                  " object"))
        return HttpResponseRedirect(reverse('admin:page_page_changelist'))

    def has_delete_permission(self, request, obj=None):
        if not settings.FEINCMS_SINGLETON_TEMPLATE_DELETION_ALLOWED:
            if obj and obj.template.singleton:
                return False
        return super(PageAdmin, self).has_delete_permission(request, obj=obj)

    def is_visible_admin(self, page):
        """
        Instead of just showing an on/off boolean, also indicate whether this
        page is not visible because of publishing dates or inherited status.
        """
        if not hasattr(self, "_visible_pages"):
            # Sanity check in case this is not already defined
            self._visible_pages = list()

        if page.parent_id and page.parent_id not in self._visible_pages:
            # parent page's invisibility is inherited
            if page.id in self._visible_pages:
                self._visible_pages.remove(page.id)
            return tree_editor.ajax_editable_boolean_cell(page,
                                                          'active',
                                                          override=False,
                                                          text=_('inherited'))

        if page.active and page.id not in self._visible_pages:
            # is active but should not be shown, so visibility limited by
            # extension: show a "not active"
            return tree_editor.ajax_editable_boolean_cell(page,
                                                          'active',
                                                          override=False,
                                                          text=_('extensions'))

        return tree_editor.ajax_editable_boolean_cell(page, 'active')

    is_visible_admin.allow_tags = True
    is_visible_admin.short_description = _('is active')
    is_visible_admin.editable_boolean_field = 'active'

    # active toggle needs more sophisticated result function
    def is_visible_recursive(self, page):
        retval = []
        for c in page.get_descendants(include_self=True):
            retval.append(self.is_visible_admin(c))
        return retval

    is_visible_admin.editable_boolean_result = is_visible_recursive