Permalink
Browse files

Saner defaults for plugins

* Fixes #1373.
* The default name for plugins is now nicer.
* The render method of plugins now by default adds.
  the instance and placeholder to the context and
  returns it, eliminating the need to overwrite this
  method in simple plugins.
  • Loading branch information...
1 parent 764702a commit 3ebfde4b9a6cd88ffb06725f712a3c36415d4874 @ojii committed Oct 11, 2012
Showing with 35 additions and 11 deletions.
  1. +8 −5 cms/plugin_base.py
  2. +17 −0 cms/tests/plugins.py
  3. +10 −6 docs/extending_cms/custom_plugins.rst
View
13 cms/plugin_base.py
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
+import re
from cms.exceptions import SubClassNeededError, Deprecated
from cms.models import CMSPlugin
from django import forms
from django.conf import settings
from django.contrib import admin
from django.core.exceptions import ImproperlyConfigured
-from django.db.models.options import get_verbose_name
from django.forms.models import ModelForm
from django.utils.encoding import smart_str
from django.utils.translation import ugettext_lazy as _
@@ -71,7 +71,7 @@ def __new__(cls, name, bases, attrs):
]
# Set default name
if not new_plugin.name:
- new_plugin.name = get_verbose_name(new_plugin.__name__)
+ new_plugin.name = re.sub("([a-z])([A-Z])","\g<1> \g<2>", name)
return new_plugin
@@ -83,7 +83,7 @@ class CMSPluginBase(admin.ModelAdmin):
form = None
change_form_template = "admin/cms/page/plugin_change_form.html"
# Should the plugin be rendered in the admin?
- admin_preview = True
+ admin_preview = False
render_template = None
# Should the plugin be rendered at all, or doesn't it have any output?
@@ -106,8 +106,11 @@ def __init__(self, model=None, admin_site=None):
self.placeholder = None
self.page = None
+
def render(self, context, instance, placeholder):
- raise NotImplementedError("render needs to be implemented")
+ context['instance'] = instance
+ context['placeholder'] = placeholder
+ return context
@property
def parent(self):
@@ -223,4 +226,4 @@ def pluginmedia(self):
def get_plugin_media(self, request, context, plugin):
raise Deprecated(
"CMSPluginBase.get_plugin_media is deprecated in favor of django-sekizai"
- )
+ )
View
17 cms/tests/plugins.py
@@ -25,6 +25,7 @@
from cms.test_utils.util.context_managers import SettingsOverride
from cms.utils.copy_plugins import copy_plugins_to
from django.conf import settings
+from django.contrib import admin
from django.contrib.auth.models import User
from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.core.files.uploadedfile import SimpleUploadedFile
@@ -999,3 +1000,19 @@ def test_link_or_page(self):
picture.url = "test"
self.assertRaises(ValidationError, picture.clean)
+
+class SimplePluginTests(TestCase):
+ def test_simple_naming(self):
+ class MyPlugin(CMSPluginBase):
+ render_template = 'base.html'
+ self.assertEqual(MyPlugin.name, 'My Plugin')
+
+ def test_simple_context(self):
+ class MyPlugin(CMSPluginBase):
+ render_template = 'base.html'
+ plugin = MyPlugin(ArticlePluginModel, admin.site)
+ context = {}
+ out_context = plugin.render(context, 1, 2)
+ self.assertEqual(out_context['instance'], 1)
+ self.assertEqual(out_context['placeholder'], 2)
+ self.assertIs(out_context, context)
View
16 docs/extending_cms/custom_plugins.rst
@@ -106,12 +106,8 @@ In there, you place your plugins. For our example, include the following code::
class HelloPlugin(CMSPluginBase):
model = CMSPlugin
- name = _("Hello Plugin")
render_template = "hello_plugin.html"
- def render(self, context, instance, placeholder):
- return context
-
plugin_pool.register_plugin(HelloPlugin)
Now we're almost done. All that's left is to add the template. Add the
@@ -139,10 +135,11 @@ There are three required attributes on those classes:
closely in a bit).
* ``name``: The name of your plugin as displayed in the admin. It is generally
good practice to mark this string as translatable using
- :func:`django.utils.translation.ugettext_lazy`, however this is optional.
+ :func:`django.utils.translation.ugettext_lazy`, however this is optional. By
+ default the name is a nicer version of the class name.
* ``render_template``: The template to render this plugin with.
-In addition to those three attributes, you must also define a
+In addition to those three attributes, you can also define a
:meth:`render` method on your subclasses. It is specifically this `render`
method that is the **view** for your plugin.
@@ -156,6 +153,13 @@ This method must return a dictionary or an instance of
:class:`django.template.Context`, which will be used as context to render the
plugin template.
+.. versionadded:: 2.4
+
+By default this method will add ``instance`` and ``placeholder`` to the
+context, which means for simple plugins, there is no need to overwrite this
+method.
+
+
*********************
Storing configuration

0 comments on commit 3ebfde4

Please sign in to comment.