Exemple #1
0
    def test_list_plugins(self):
        placeholder = Placeholder.objects.create(slot="test")
        add_plugin(placeholder, TextPlugin, "en", body="en body")
        add_plugin(placeholder, TextPlugin, "en", body="en body")
        link_plugin = add_plugin(placeholder,
                                 "LinkPlugin",
                                 "en",
                                 name="A Link",
                                 url="https://www.django-cms.org")
        self.assertEqual(
            CMSPlugin.objects.filter(plugin_type=PLUGIN).count(), 2)
        self.assertEqual(
            CMSPlugin.objects.filter(plugin_type="LinkPlugin").count(), 1)

        # create a CMSPlugin with an unsaved instance
        instanceless_plugin = CMSPlugin(language="en",
                                        plugin_type="TextPlugin")
        instanceless_plugin.save()

        # create a bogus CMSPlugin to simulate one which used to exist but
        # is no longer installed
        bogus_plugin = CMSPlugin(language="en", plugin_type="BogusPlugin")
        bogus_plugin.save()

        report = plugin_report()

        # there should be reports for three plugin types
        self.assertEqual(len(report), 3)

        # check the bogus plugin
        bogus_plugins_report = report[0]
        self.assertEqual(bogus_plugins_report["model"], None)

        self.assertEqual(bogus_plugins_report["type"], u'BogusPlugin')

        self.assertEqual(bogus_plugins_report["instances"][0], bogus_plugin)

        # check the link plugin
        link_plugins_report = report[1]
        self.assertEqual(link_plugins_report["model"], link_plugin.__class__)

        self.assertEqual(link_plugins_report["type"], u'LinkPlugin')

        self.assertEqual(
            link_plugins_report["instances"][0].get_plugin_instance()[0],
            link_plugin)

        # check the text plugins
        text_plugins_report = report[2]
        self.assertEqual(text_plugins_report["model"], TextPlugin.model)

        self.assertEqual(text_plugins_report["type"], u'TextPlugin')

        self.assertEqual(len(text_plugins_report["instances"]), 3)

        self.assertEqual(text_plugins_report["instances"][2],
                         instanceless_plugin)

        self.assertEqual(text_plugins_report["unsaved_instances"],
                         [instanceless_plugin])
Exemple #2
0
    def test_check_plugin_instances(self):
        self.assertCheck(True, warnings=0, errors=0)

        placeholder = Placeholder.objects.create(slot="test")
        add_plugin(placeholder, TextPlugin, "en", body="en body")
        add_plugin(placeholder, TextPlugin, "en", body="en body")
        add_plugin(placeholder,
                   "LinkPlugin",
                   "en",
                   name="A Link",
                   external_link="https://www.django-cms.org")

        # create a CMSPlugin with an unsaved instance
        instanceless_plugin = CMSPlugin(language="en",
                                        plugin_type="TextPlugin")
        instanceless_plugin.save()

        self.assertCheck(False, warnings=0, errors=2)

        # create a bogus CMSPlugin to simulate one which used to exist but
        # is no longer installed
        bogus_plugin = CMSPlugin(language="en", plugin_type="BogusPlugin")
        bogus_plugin.save()

        self.assertCheck(False, warnings=0, errors=3)
    def test_check_plugin_instances(self):
        self.assertCheck(True, warnings=0, errors=0)

        apps = ["cms", "menus", "sekizai", "cms.test_utils.project.sampleapp"]
        with SettingsOverride(INSTALLED_APPS=apps):
            placeholder = Placeholder.objects.create(slot="test")
            add_plugin(placeholder, TextPlugin, "en", body="en body")
            add_plugin(placeholder, TextPlugin, "en", body="en body")
            link_plugin = add_plugin(placeholder,
                                     "LinkPlugin",
                                     "en",
                                     name="A Link",
                                     url="https://www.django-cms.org")

            # create a CMSPlugin with an unsaved instance
            instanceless_plugin = CMSPlugin(language="en",
                                            plugin_type="TextPlugin")
            instanceless_plugin.save()

            self.assertCheck(False, warnings=0, errors=2)

            # create a bogus CMSPlugin to simulate one which used to exist but
            # is no longer installed
            bogus_plugin = CMSPlugin(language="en", plugin_type="BogusPlugin")
            bogus_plugin.save()

            self.assertCheck(False, warnings=0, errors=3)
Exemple #4
0
    def test_delete_orphaned_plugins(self):
        apps = ["cms", "menus", "sekizai", "cms.test_utils.project.sampleapp"]
        with SettingsOverride(INSTALLED_APPS=apps):
            placeholder = Placeholder.objects.create(slot="test")
            add_plugin(placeholder, TextPlugin, "en", body="en body")
            add_plugin(placeholder, TextPlugin, "en", body="en body")
            link_plugin = add_plugin(placeholder,
                                     "LinkPlugin",
                                     "en",
                                     name="A Link",
                                     url="https://www.django-cms.org")

            instanceless_plugin = CMSPlugin(language="en",
                                            plugin_type="TextPlugin")
            instanceless_plugin.save()

            # create a bogus CMSPlugin to simulate one which used to exist but
            # is no longer installed
            bogus_plugin = CMSPlugin(language="en", plugin_type="BogusPlugin")
            bogus_plugin.save()

            report = plugin_report()

            # there should be reports for three plugin types
            self.assertEqual(len(report), 3)

            # check the bogus plugin
            bogus_plugins_report = report[0]
            self.assertEqual(len(bogus_plugins_report["instances"]), 1)

            # check the link plugin
            link_plugins_report = report[1]
            self.assertEqual(len(link_plugins_report["instances"]), 1)

            # check the text plugins
            text_plugins_report = report[2]
            self.assertEqual(len(text_plugins_report["instances"]), 3)

            self.assertEqual(len(text_plugins_report["unsaved_instances"]), 1)

            management.call_command('cms',
                                    'delete_orphaned_plugins',
                                    stdout=StringIO(),
                                    interactive=False)
            report = plugin_report()

            # there should be reports for two plugin types (one should have been deleted)
            self.assertEqual(len(report), 2)

            # check the link plugin
            link_plugins_report = report[0]
            self.assertEqual(len(link_plugins_report["instances"]), 1)

            # check the text plugins
            text_plugins_report = report[1]
            self.assertEqual(len(text_plugins_report["instances"]), 2)

            self.assertEqual(len(text_plugins_report["unsaved_instances"]), 0)
    def test_delete_orphaned_plugins(self):
        placeholder = Placeholder.objects.create(slot="test")
        add_plugin(placeholder, TextPlugin, "en", body="en body")
        add_plugin(placeholder, TextPlugin, "en", body="en body")
        add_plugin(placeholder,
                   "LinkPlugin",
                   "en",
                   name="A Link",
                   external_link="https://www.django-cms.org")

        instanceless_plugin = CMSPlugin(language="en",
                                        plugin_type="TextPlugin")
        instanceless_plugin.save()

        # create a bogus CMSPlugin to simulate one which used to exist but
        # is no longer installed
        bogus_plugin = CMSPlugin(language="en", plugin_type="BogusPlugin")
        bogus_plugin.save()

        report = plugin_report()

        # there should be reports for three plugin types
        self.assertEqual(len(report), 3)

        # check the bogus plugin
        bogus_plugins_report = report[0]
        self.assertEqual(len(bogus_plugins_report["instances"]), 1)

        # check the link plugin
        link_plugins_report = report[1]
        self.assertEqual(len(link_plugins_report["instances"]), 1)

        # check the text plugins
        text_plugins_report = report[2]
        self.assertEqual(len(text_plugins_report["instances"]), 3)

        self.assertEqual(len(text_plugins_report["unsaved_instances"]), 1)

        out = io.StringIO()
        management.call_command('cms',
                                'delete-orphaned-plugins',
                                interactive=False,
                                stdout=out)
        report = plugin_report()

        # there should be reports for two plugin types (one should have been deleted)
        self.assertEqual(len(report), 2)

        # check the link plugin
        link_plugins_report = report[0]
        self.assertEqual(len(link_plugins_report["instances"]), 1)

        # check the text plugins
        text_plugins_report = report[1]
        self.assertEqual(len(text_plugins_report["instances"]), 2)

        self.assertEqual(len(text_plugins_report["unsaved_instances"]), 0)
Exemple #6
0
    def test_inherit_plugin_with_empty_plugin(self):
        inheritfrompage = create_page('page to inherit from',
                                      'nav_playground.html',
                                      'en', published=True)

        body = inheritfrompage.placeholders.get(slot="body")
        empty_plugin = CMSPlugin(
            plugin_type='TextPlugin', # create an empty plugin
            placeholder=body,
            position=1,
            language='en',
        )
        empty_plugin.insert_at(None, position='last-child', save=True)
        other_page = create_page('other page', 'nav_playground.html', 'en', published=True)
        inherited_body = other_page.placeholders.get(slot="body")
        inherit_plugin = InheritPagePlaceholder(
            plugin_type='InheritPagePlaceholderPlugin',
            placeholder=inherited_body,
            position=1,
            language='en',
            from_page=inheritfrompage,
            from_language='en'
        )
        inherit_plugin.insert_at(None, position='last-child', save=True)
        add_plugin(inherited_body, "TextPlugin", "en", body="foobar")
        # this should not fail, even if there in an empty plugin
        rendered = inherited_body.render(context=self.get_context(other_page.get_absolute_url()), width=200)
        self.assertIn("foobar", rendered)
Exemple #7
0
    def test_delete_with_plugins(self):
        """
        Check that plugins and placeholders get correctly deleted when we delete
        a page!
        """
        Text = self.get_plugin_model('TextPlugin')
        home = create_page("home", "nav_playground.html", "en")
        page = create_page("page", "nav_playground.html", "en")
        page.rescan_placeholders() # create placeholders
        placeholder = page.placeholders.all()[0]
        plugin_base = CMSPlugin(
            plugin_type='TextPlugin',
            placeholder=placeholder,
            position=1,
            language=settings.LANGUAGES[0][0]
        )
        plugin_base = plugin_base.add_root(instance=plugin_base)

        plugin = Text(body='')
        plugin_base.set_base_attr(plugin)
        plugin.save()
        self.assertEqual(CMSPlugin.objects.count(), 1)
        self.assertEqual(Text.objects.count(), 1)
        self.assertTrue(Placeholder.objects.count() > 2)
        page.delete()
        home.delete()
        self.assertEqual(CMSPlugin.objects.count(), 0)
        self.assertEqual(Text.objects.count(), 0)
        self.assertEqual(Placeholder.objects.count(), 0)
        self.assertEqual(Page.objects.count(), 0)
Exemple #8
0
    def test_delete_with_plugins(self):
        """
        Check that plugins and placeholders get correctly deleted when we delete
        a page!
        """
        page = create_page("page", "nav_playground.html", "en")
        page.rescan_placeholders() # create placeholders
        placeholder = page.placeholders.all()[0]
        plugin_base = CMSPlugin(
            plugin_type='TextPlugin',
            placeholder=placeholder,
            position=1,
            language=settings.LANGUAGES[0][0]
        )
        plugin_base.insert_at(None, position='last-child', save=False)

        plugin = Text(body='')
        plugin_base.set_base_attr(plugin)
        plugin.save()
        self.assertEqual(CMSPlugin.objects.count(), 1)
        self.assertEqual(Text.objects.count(), 1)
        self.assertTrue(Placeholder.objects.count() > 0)
        page.delete()
        self.assertEqual(CMSPlugin.objects.count(), 0)
        self.assertEqual(Text.objects.count(), 0)
        self.assertEqual(Placeholder.objects.count(), 0)
Exemple #9
0
def add_plugin(placeholder,
               plugin_type,
               language,
               position='last-child',
               target=None,
               **data):
    """
    Add a plugin to a placeholder
    
    See docs/extending_cms/api_reference.rst for more info
    """
    # validate placeholder
    assert isinstance(placeholder, Placeholder)

    # validate and normalize plugin type
    plugin_model, plugin_type = _verify_plugin_type(plugin_type)

    max_pos = CMSPlugin.objects.filter(
        language=language, placeholder=placeholder).aggregate(
            Max('position'))['position__max'] or 0

    plugin_base = CMSPlugin(plugin_type=plugin_type,
                            placeholder=placeholder,
                            position=max_pos + 1,
                            language=language)
    plugin_base.insert_at(target, position=position, save=False)

    plugin = plugin_model(**data)
    plugin_base.set_base_attr(plugin)
    plugin.save()
    return plugin
    def save_body(self, placeholder, desc):
        language = settings.LANGUAGE_CODE
        try:
            plugin = CMSPlugin.objects.get(placeholder=placeholder,
                                           position=0,
                                           language=language)
            plugin.body = desc
        except CMSPlugin.DoesNotExist:
            plugin = CMSPlugin(language=language,
                               plugin_type='TextPlugin',
                               position=0,
                               placeholder=placeholder)
            plugin.save()

        if plugin:
            text = Text()
            #text.set_base_attr(plugin)
            text.pk = plugin.pk
            text.id = plugin.pk
            text.placeholder = placeholder
            text.position = plugin.position
            text.plugin_type = plugin.plugin_type
            text.tree_id = plugin.tree_id
            text.lft = plugin.lft
            text.rght = plugin.rght
            text.level = plugin.level
            text.cmsplugin_ptr = plugin
            text.publisher_public_id = None
            text.public_id = None
            text.published = False
            text.language = language
            text.body = desc
            text.save()
Exemple #11
0
    def add_plugin(self, request):
        # only allow POST
        if request.method != "POST":
            raise Http404
        plugin_type = request.POST['plugin_type']
        if not has_plugin_permission(request.user, plugin_type, "add"):
            return HttpResponseForbidden(
                "You don't have permission to add plugins")

        placeholder_id = request.POST.get('placeholder', None)
        position = None
        language = get_language_from_request(request)
        parent = None
        # check if we got a placeholder (id)
        if placeholder_id:
            placeholder = get_object_or_404(Placeholder, pk=placeholder_id)
        else:  # else get the parent_id
            parent_id = request.POST.get('parent_id', None)
            if not parent_id:  # if we get neither a placeholder nor a parent, bail out
                raise Http404
            parent = get_object_or_404(CMSPlugin, pk=parent_id)
            placeholder = parent.placeholder

        # check add permissions on placeholder
        if not placeholder.has_add_permission(request):
            return HttpResponseForbidden(
                _("You don't have permission to add content here."))

        # check the limits defined in CMS_PLACEHOLDER_CONF for this placeholder
        limits = settings.CMS_PLACEHOLDER_CONF.get(placeholder.slot,
                                                   {}).get('limits', None)
        if limits:
            count = placeholder.cmsplugin_set.count()
            global_limit = limits.get("global", None)
            type_limit = limits.get(plugin_type, None)
            # check the global limit first
            if global_limit and count >= global_limit:
                return HttpResponseBadRequest(
                    "This placeholder already has the maximum number of plugins."
                )
            elif type_limit:  # then check the type specific limit
                type_count = CMSPlugin.objects.filter(
                    language=language,
                    placeholder=placeholder,
                    plugin_type=plugin_type).count()
                if type_count >= type_limit:
                    return HttpResponseBadRequest(
                        "This placeholder already has the maximum number (%s) "
                        "of %s plugins." % (type_limit, plugin_type))

        # actually add the plugin
        plugin = CMSPlugin(language=language,
                           plugin_type=plugin_type,
                           position=position,
                           placeholder=placeholder,
                           parent=parent)
        plugin.save()

        # returns it's ID as response
        return HttpResponse(str(plugin.pk))
Exemple #12
0
    def add_plugin(self, request):
        """
        POST request should have the following data:

        - placeholder_id
        - plugin_type
        - plugin_language
        - plugin_parent (optional)
        """
        parent = None
        plugin_type = request.POST['plugin_type']
        placeholder_id = request.POST.get('placeholder_id', None)
        placeholder = get_object_or_404(Placeholder, pk=placeholder_id)
        parent_id = request.POST.get('plugin_parent', None)
        language = request.POST.get('plugin_language') or get_language_from_request(request)
        if not self.has_add_plugin_permission(request, placeholder, plugin_type):
            return HttpResponseForbidden(force_text(_('You do not have permission to add a plugin')))
        try:
            has_reached_plugin_limit(placeholder, plugin_type, language,
                                     template=self.get_placeholder_template(request, placeholder))
        except PluginLimitReached as er:
            return HttpResponseBadRequest(er)
            # page add-plugin
        if not parent_id:
            position = request.POST.get('plugin_order',
                                        CMSPlugin.objects.filter(language=language, placeholder=placeholder).count())
        # in-plugin add-plugin
        else:
            parent = get_object_or_404(CMSPlugin, pk=parent_id)
            placeholder = parent.placeholder
            position = request.POST.get('plugin_order',
                                        CMSPlugin.objects.filter(language=language, parent=parent).count())
            # placeholder (non-page) add-plugin

        # Sanity check to make sure we're not getting bogus values from JavaScript:
        if settings.USE_I18N:
            if not language or not language in [lang[0] for lang in settings.LANGUAGES]:
                return HttpResponseBadRequest(force_text(_("Language must be set to a supported language!")))
            if parent and parent.language != language:
                return HttpResponseBadRequest(force_text(_("Parent plugin language must be same as language!")))
        else:
            language = settings.LANGUAGE_CODE
        plugin = CMSPlugin(language=language, plugin_type=plugin_type, position=position, placeholder=placeholder)

        if parent:
            plugin.position = CMSPlugin.objects.filter(parent=parent).count()
            plugin.parent_id = parent.pk
        plugin.save()
        self.post_add_plugin(request, placeholder, plugin)
        response = {
            'url': force_text(
                admin_reverse("%s_%s_edit_plugin" % (self.model._meta.app_label, self.model._meta.model_name),
                        args=[plugin.pk])),
            'delete': force_text(
                admin_reverse("%s_%s_delete_plugin" % (self.model._meta.app_label, self.model._meta.model_name),
                        args=[plugin.pk])),
            'breadcrumb': plugin.get_breadcrumb(),
        }
        return HttpResponse(json.dumps(response), content_type='application/json')
 def add_plugin(self, request):
     if request.method != "POST":
         raise Http404
     plugin_type = request.POST['plugin_type']
     placeholder_id = request.POST.get('placeholder', None)
     position = None
     language = get_language_from_request(request)
     if not placeholder_id:
         parent_id = request.POST.get('parent_id', None)
         if not parent_id:
             raise Http404
         parent = get_object_or_404(CMSPlugin, pk=parent_id)
         plugin = CMSPlugin(language=language, plugin_type=plugin_type,
             position=position, parent=parent, placeholder=parent.placeholder)
     else:
         placeholder = get_object_or_404(Placeholder, pk=placeholder_id)
         plugin = CMSPlugin(language=language, plugin_type=plugin_type,
             position=position, placeholder=placeholder) 
     plugin.save()
     return HttpResponse(str(plugin.pk))
Exemple #14
0
def add_plugin(placeholder,
               plugin_type,
               language,
               position='last-child',
               target=None,
               **data):
    """
    Add a plugin to a placeholder
    
    See docs/extending_cms/api_reference.rst for more info
    """
    # validate placeholder
    assert isinstance(placeholder, Placeholder)

    # validate and normalize plugin type
    plugin_model, plugin_type = _verify_plugin_type(plugin_type)
    if target:
        if position == 'last-child':
            new_pos = CMSPlugin.objects.filter(language=language,
                                               parent=target,
                                               tree_id=target.tree_id).count()
        elif position == 'first-child':
            new_pos = 0
        elif position == 'left':
            new_pos = target.position
        elif position == 'right':
            new_pos = target.position + 1
        else:
            raise Exception('position not supported: %s' % position)
        for pl in CMSPlugin.objects.filter(language=language,
                                           parent=target.parent_id,
                                           tree_id=target.tree_id,
                                           position__gte=new_pos):
            pl.position += 1
            pl.save()
    else:
        new_pos = CMSPlugin.objects.filter(language=language,
                                           parent__isnull=True,
                                           placeholder=placeholder).count()

    plugin_base = CMSPlugin(plugin_type=plugin_type,
                            placeholder=placeholder,
                            position=new_pos,
                            language=language)
    plugin_base.insert_at(target, position=position, save=False)

    plugin = plugin_model(**data)
    plugin_base.set_base_attr(plugin)
    plugin.save()
    return plugin
Exemple #15
0
    def test_empty_plugin_is_ignored(self):
        page = create_page("page", "nav_playground.html", "en")

        placeholder = page.placeholders.get(slot='body')

        plugin = CMSPlugin(plugin_type='TextPlugin',
                           placeholder=placeholder,
                           position=1,
                           language=self.FIRST_LANG)
        plugin.insert_at(None, position='last-child', save=True)

        # this should not raise any errors, but just ignore the empty plugin
        out = placeholder.render(self.get_context(), width=300)
        self.assertFalse(len(out))
        self.assertFalse(len(placeholder._en_plugins_cache))
Exemple #16
0
    def setUp(self):
        super().setUp()

        self.hats = Theme.objects.create(
            name='Hats',
            slug='hats',
            blurb='People must wear hats to the party',
            description='Any hat goes but Red Hat or Fedora get extra points')

        self.orange = Theme.objects.create(
            name='Orange clothes',
            slug='orange-clothes',
            blurb='People must wear orange clothes to the party',
            description='Come dressed as an orange for extra points')

        self.instance = CMSPlugin()
Exemple #17
0
 def add_plugin(self, user=None, page=None, placeholder=None, language='en', body=''):
     if not placeholder:
         if page:
             placeholder = page.placeholders.get(slot__iexact='Right-Column')
         else:
             placeholder = page.placeholders.get(slot__iexact='Right-Column')
         
     plugin_base = CMSPlugin(
         plugin_type='TextPlugin',
         placeholder=placeholder, 
         position=1, 
         language=language
     )
     plugin_base.insert_at(None, position='last-child', commit=False)
             
     plugin = Text(body=body)
     plugin_base.set_base_attr(plugin)
     plugin.save()
     return plugin.pk
Exemple #18
0
def add_plugin(placeholder,
               plugin_type,
               language,
               position='last-child',
               **data):
    """
    Taken from django-cms api (in newer versions)
    https://github.com/divio/django-cms/blob/b8633b42efcd137d96e1e3f42e004cb7595768fe/cms/api.py
    """
    assert isinstance(placeholder, Placeholder)
    plugin_model = plugin_type.model
    plugin_type = plugin_type.__name__
    plugin_base = CMSPlugin(plugin_type=plugin_type,
                            placeholder=placeholder,
                            position=1,
                            language=language)
    plugin_base.insert_at(None, position='last-child', commit=False)
    plugin = plugin_model(**data)
    plugin_base.set_base_attr(plugin)
    plugin.save()
    return plugin
Exemple #19
0
class PlaceholderAdmin(ModelAdmin):
    render_placeholder_language_tabs = True
    change_form_template = 'admin/placeholders/placeholder/change_form.html'

    class Media:
        css = {
            'all': [
                cms_static_url(path) for path in (
                    'css/rte.css',
                    'css/change_form.css',
                    'css/jquery.dialog.css',
                    'css/plugin_editor.css',
                )
            ]
        }
        js = [
            cms_static_url(path) for path in [
                'js/plugins/admincompat.js',
                'js/csrf.js',
                'js/libs/jquery.query.js',
                'js/libs/jquery.ui.core.js',
                'js/libs/jquery.ui.dialog.js',
            ]
        ]

    def get_fieldsets(self, request, obj=None):
        """
        Get fieldsets to enforce correct fieldsetting of placeholder fields
        """
        form = self.get_form(request, obj)
        placeholder_fields = self._get_placeholder_fields(form)
        if self.declared_fieldsets:
            # check those declared fieldsets
            fieldsets = list(deepcopy(self.declared_fieldsets))
            for label, fieldset in fieldsets:
                fields = list(fieldset['fields'])
                for field in fieldset['fields']:
                    if field in placeholder_fields:
                        if (len(fieldset['fields']) == 1
                                and 'classes' in fieldset
                                and 'plugin-holder' in fieldset['classes'] and
                                'plugin-holder-nopage' in fieldset['classes']):
                            placeholder_fields.remove(field)
                        else:
                            fields.remove(field)
                if fields:
                    fieldset['fields'] = fields
                else:
                    # no fields in the fieldset anymore, delete the fieldset
                    fieldsets.remove((label, fieldset))
            for placeholder in placeholder_fields:
                fieldsets.append((
                    self.get_label_for_placeholder(placeholder),
                    {
                        'fields': (placeholder, ),
                        'classes': (
                            'plugin-holder',
                            'plugin-holder-nopage',
                        ),
                    },
                ))
            return fieldsets
        fieldsets = []
        fieldsets.append((None, {
            'fields': [
                f for f in form.base_fields.keys()
                if not f in placeholder_fields
            ]
        }))
        for placeholder in placeholder_fields:
            fieldsets.append((self.get_label_for_placeholder(placeholder), {
                'fields': (placeholder, ),
                'classes': (
                    'plugin-holder',
                    'plugin-holder-nopage',
                ),
            }))
        readonly_fields = self.get_readonly_fields(request, obj)
        if readonly_fields:
            fieldsets.append((None, {'fields': list(readonly_fields)}))
        return fieldsets

    def get_label_for_placeholder(self, placeholder):
        return ' '.join([
            x.capitalize() for x in self.model._meta.get_field_by_name(
                placeholder)[0].verbose_name.split(' ')
        ])

    def formfield_for_dbfield(self, db_field, **kwargs):
        """
        Hook for specifying the form Field instance for a given database Field
        instance.

        If kwargs are given, they're passed to the form Field's constructor.
        """
        if isinstance(db_field, PlaceholderField):
            request = kwargs.pop("request", None)
            return db_field.formfield_for_admin(request,
                                                self.placeholder_plugin_filter,
                                                **kwargs)
        return super(PlaceholderAdmin,
                     self).formfield_for_dbfield(db_field, **kwargs)

    def get_language_from_request(self, request):
        language = request.REQUEST.get('language', None)
        if not language:
            language = get_language()
        return language

    def placeholder_plugin_filter(self, request, queryset):
        if self.render_placeholder_language_tabs:
            language = self.get_language_from_request(request)
            if language:
                queryset = queryset.filter(language=language)
        return queryset

    def change_view(self, request, object_id, form_url='', extra_context=None):
        extra_context = extra_context or {}
        extra_context.update(self.language_tab_context(request))
        tab_language = request.GET.get("language", None)
        response = super(PlaceholderAdmin,
                         self).change_view(request,
                                           object_id,
                                           extra_context=extra_context)

        if tab_language and response.status_code == 302 and response._headers[
                'location'][1] == request.path:
            location = response._headers['location']
            response._headers['location'] = (location[0], "%s?language=%s" %
                                             (location[1], tab_language))
        return response

    def language_tab_context(self, request):
        language = self.get_language_from_request(request)
        languages = [(lang, lang_name)
                     for lang, lang_name in settings.LANGUAGES]
        context = {
            'language':
            language,
            'language_tabs':
            languages,
            'show_language_tabs':
            len(languages) > 1 and self.render_placeholder_language_tabs,
        }
        return context

    def _get_placeholder_fields(self, form):
        placeholder_fields = []
        for key, value in form.base_fields.items():
            if isinstance(value, PlaceholderFormField):
                placeholder_fields.append(key)
        return placeholder_fields

    def get_urls(self):
        """
        Register the plugin specific urls (add/edit/copy/remove/move)
        """
        from django.conf.urls.defaults import patterns, url

        info = "%s_%s" % (self.model._meta.app_label,
                          self.model._meta.module_name)
        pat = lambda regex, fn: url(regex,
                                    self.admin_site.admin_view(fn),
                                    name='%s_%s' % (info, fn.__name__))

        url_patterns = patterns(
            '',
            pat(r'add-plugin/$', self.add_plugin),
            pat(r'edit-plugin/([0-9]+)/$', self.edit_plugin),
            pat(r'remove-plugin/$', self.remove_plugin),
            pat(r'move-plugin/$', self.move_plugin),
            pat(r'copy-plugins/$', self.copy_plugins),
        )
        return url_patterns + super(PlaceholderAdmin, self).get_urls()

    @xframe_options_sameorigin
    def add_plugin(self, request):
        # only allow POST
        if request.method != "POST":
            raise Http404
        plugin_type = request.POST['plugin_type']
        if not has_plugin_permission(request.user, plugin_type, "add"):
            return HttpResponseForbidden(
                "You don't have permission to add plugins")

        placeholder_id = request.POST.get('placeholder', None)
        position = None
        language = self.get_language_from_request(request)
        parent = None
        # check if we got a placeholder (id)
        if placeholder_id:
            placeholder = get_object_or_404(Placeholder, pk=placeholder_id)
        else:  # else get the parent_id
            parent_id = request.POST.get('parent_id', None)
            if not parent_id:  # if we get neither a placeholder nor a parent, bail out
                raise Http404
            parent = get_object_or_404(CMSPlugin, pk=parent_id)
            placeholder = parent.placeholder

        # check add permissions on placeholder
        if not placeholder.has_add_permission(request):
            return HttpResponseForbidden(
                _("You don't have permission to add content here."))

        try:
            has_reached_plugin_limit(placeholder, plugin_type, language)
        except PluginLimitReached, e:
            return HttpResponseBadRequest(str(e))

        # actually add the plugin
        plugin = CMSPlugin(language=language,
                           plugin_type=plugin_type,
                           position=position,
                           placeholder=placeholder,
                           parent=parent)
        plugin.save()

        # returns it's ID as response
        return HttpResponse(str(plugin.pk))
Exemple #20
0
    def test_11_copy_textplugin(self):
        """
        Test that copying of textplugins replaces references to copied plugins
        """
        
        page = self.create_page()
        
        placeholder = page.placeholders.get(slot='body')
        
        plugin_base = CMSPlugin(
            plugin_type='TextPlugin',
            placeholder=placeholder, 
            position=1, 
            language=self.FIRST_LANG)
        plugin_base.insert_at(None, position='last-child', commit=False)
                
        plugin = Text(body='')
        plugin_base.set_base_attr(plugin)
        plugin.save()
        
        plugin_ref_1_base = CMSPlugin(
            plugin_type='TextPlugin',
            placeholder=placeholder, 
            position=1, 
            language=self.FIRST_LANG)
        plugin_ref_1_base.insert_at(plugin_base, position='last-child', commit=False)    
        
        plugin_ref_1 = Text(body='')
        plugin_ref_1_base.set_base_attr(plugin_ref_1)
        plugin_ref_1.save()
        
        plugin_ref_2_base = CMSPlugin(
            plugin_type='TextPlugin',
            placeholder=placeholder, 
            position=2, 
            language=self.FIRST_LANG)
        plugin_ref_2_base.insert_at(plugin_base, position='last-child', commit=False)    
        
        plugin_ref_2 = Text(body='')
        plugin_ref_2_base.set_base_attr(plugin_ref_2)

        plugin_ref_2.save()
        
        plugin.body = plugin_tags_to_admin_html(' {{ plugin_object %s }} {{ plugin_object %s }} ' % (str(plugin_ref_1.pk), str(plugin_ref_2.pk)))
        plugin.save()
        self.assertEquals(plugin.pk, 1)
        page_data = self.get_new_page_data()

        #create 2nd language page
        page_data.update({
            'language': self.SECOND_LANG,
            'title': "%s %s" % (page.get_title(), self.SECOND_LANG),
        })
        response = self.client.post(URL_CMS_PAGE_CHANGE % page.pk + "?language=%s" % self.SECOND_LANG, page_data)
        self.assertRedirects(response, URL_CMS_PAGE)
        
        self.assertEquals(CMSPlugin.objects.filter(language=self.FIRST_LANG).count(), 3)
        self.assertEquals(CMSPlugin.objects.filter(language=self.SECOND_LANG).count(), 0)
        self.assertEquals(CMSPlugin.objects.count(), 3)
        self.assertEquals(Page.objects.all().count(), 1)
        
        copy_data = {
            'placeholder': placeholder.pk,
            'language': self.SECOND_LANG,
            'copy_from': self.FIRST_LANG,
        }
        response = self.client.post(URL_CMS_PAGE + "copy-plugins/", copy_data)
        self.assertEquals(response.status_code, 200)
        self.assertEqual(response.content.count('<li '), 3)
        # assert copy success
        self.assertEquals(CMSPlugin.objects.filter(language=self.FIRST_LANG).count(), 3)
        self.assertEquals(CMSPlugin.objects.filter(language=self.SECOND_LANG).count(), 3)
        self.assertEquals(CMSPlugin.objects.count(), 6)

        new_plugin = Text.objects.get(pk=6)
        self.assertEquals(plugin_tags_to_id_list(new_plugin.body), [u'4', u'5'])
Exemple #21
0
def add_plugin(placeholder, plugin_type, language, position='last-child',
               target=None, **data):
    """
    Add a plugin to a placeholder

    See docs/extending_cms/api_reference.rst for more info
    """
    # validate placeholder
    assert isinstance(placeholder, Placeholder)

    # validate and normalize plugin type
    plugin_model, plugin_type = _verify_plugin_type(plugin_type)
    if target:
        if position == 'last-child':
            if CMSPlugin.node_order_by:
                position = 'sorted-child'
            new_pos = CMSPlugin.objects.filter(parent=target).count()
            parent_id = target.pk
        elif position == 'first-child':
            new_pos = 0
            if CMSPlugin.node_order_by:
                position = 'sorted-child'
            parent_id = target.pk
        elif position == 'left':
            new_pos = target.position
            if CMSPlugin.node_order_by:
                position = 'sorted-sibling'
            parent_id = target.parent_id
        elif position == 'right':
            new_pos = target.position + 1
            if CMSPlugin.node_order_by:
                position = 'sorted-sibling'
            parent_id = target.parent_id
        else:
            raise Exception('position not supported: %s' % position)
        if position == 'last-child' or position == 'first-child':
            qs = CMSPlugin.objects.filter(language=language, parent=target, position__gte=new_pos,
                                          placeholder=placeholder)
        else:
            qs = CMSPlugin.objects.filter(language=language, parent=target.parent_id, position__gte=new_pos,
                                          placeholder=placeholder)
        for pl in qs:
            pl.position += 1
            pl.save()
    else:
        if position == 'last-child':
            new_pos = CMSPlugin.objects.filter(language=language, parent__isnull=True, placeholder=placeholder).count()
        else:
            new_pos = 0
            for pl in CMSPlugin.objects.filter(language=language, parent__isnull=True, position__gte=new_pos,
                                               placeholder=placeholder):
                pl.position += 1
                pl.save()
        parent_id = None
    plugin_base = CMSPlugin(
        plugin_type=plugin_type,
        placeholder=placeholder,
        position=new_pos,
        language=language,
        parent_id=parent_id,
    )

    plugin_base = plugin_base.add_root(instance=plugin_base)

    if target:
        plugin_base = plugin_base.move(target, pos=position)
    plugin = plugin_model(**data)
    plugin_base.set_base_attr(plugin)
    plugin.save()
    return plugin
Exemple #22
0
    def test_list_plugins(self):
        out = io.StringIO()
        placeholder = Placeholder.objects.create(slot="test")
        add_plugin(placeholder, TextPlugin, "en", body="en body")
        add_plugin(placeholder, TextPlugin, "en", body="en body")
        link_plugin = add_plugin(placeholder,
                                 "LinkPlugin",
                                 "en",
                                 name="A Link",
                                 external_link="https://www.django-cms.org")
        self.assertEqual(
            CMSPlugin.objects.filter(plugin_type=PLUGIN).count(), 2)
        self.assertEqual(
            CMSPlugin.objects.filter(plugin_type="LinkPlugin").count(), 1)

        # create a CMSPlugin with an unsaved instance
        instanceless_plugin = CMSPlugin(language="en",
                                        plugin_type="TextPlugin")
        instanceless_plugin.save()

        # create a bogus CMSPlugin to simulate one which used to exist but
        # is no longer installed
        bogus_plugin = CMSPlugin(language="en", plugin_type="BogusPlugin")
        bogus_plugin.save()

        with mock.patch(
                'cms.management.commands.subcommands.list.plugin_report'
        ) as report_fn:
            management.call_command('cms',
                                    'list',
                                    'plugins',
                                    interactive=False,
                                    stdout=out)
            report_fn.assert_called_once()

        report = plugin_report()

        # there should be reports for three plugin types
        self.assertEqual(len(report), 3)

        # check the bogus plugin
        bogus_plugins_report = report[0]
        self.assertEqual(bogus_plugins_report["model"], None)

        self.assertEqual(bogus_plugins_report["type"], u'BogusPlugin')

        self.assertEqual(bogus_plugins_report["instances"][0], bogus_plugin)

        # check the link plugin
        link_plugins_report = report[1]
        self.assertEqual(link_plugins_report["model"], link_plugin.__class__)

        self.assertEqual(link_plugins_report["type"], u'LinkPlugin')

        self.assertEqual(
            link_plugins_report["instances"][0].get_plugin_instance()[0],
            link_plugin)

        # check the text plugins
        text_plugins_report = report[2]
        self.assertEqual(text_plugins_report["model"], TextPlugin.model)

        self.assertEqual(text_plugins_report["type"], u'TextPlugin')

        self.assertEqual(len(text_plugins_report["instances"]), 3)

        self.assertEqual(text_plugins_report["instances"][2],
                         instanceless_plugin)

        self.assertEqual(text_plugins_report["unsaved_instances"],
                         [instanceless_plugin])