Skip to content

Commit

Permalink
Moved plugin processors to a seperate file
Browse files Browse the repository at this point in the history
Changed the PluginRender class to a function since the class was pointless
Using django-load (copied to cms/utils/django_load.py because it's only a single file) for loading of apphooks, plugins, menus and plugin processors to remove boilerplate code
  • Loading branch information
Jonas Obrist committed Mar 4, 2011
1 parent 668fc0e commit 5a595fb
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 123 deletions.
24 changes: 6 additions & 18 deletions cms/apphook_pool.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
from cms.exceptions import AppAllreadyRegistered
from cms.utils.django_load import load, iterload_objects
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.importlib import import_module

class ApphookPool(object):
def __init__(self):
Expand All @@ -15,26 +15,14 @@ def discover_apps(self):
return
#import all the modules
if settings.CMS_APPHOOKS:

for app in settings.CMS_APPHOOKS:
self.block_register = True
path = ".".join(app.split(".")[:-1])
class_name = app.split(".")[-1]
module = import_module(path)
cls = getattr(module, class_name, None)
if cls is None:
raise ImproperlyConfigured(
"Cannot find class %s" % app
)
self.block_register = True
for cls in iterload_objects(settings.CMS_APPHOOKS):
self.block_register = False
self.register(cls)
self.block_register = True
self.block_register = False
else:
for app in settings.INSTALLED_APPS:
cms_app = '%s.cms_app' % app
try:
import_module(cms_app)
except ImportError:
pass
load('cms_app')
self.discovered = True

def clear(self):
Expand Down
11 changes: 5 additions & 6 deletions cms/models/pluginmodel.py
@@ -1,19 +1,19 @@
# -*- coding: utf-8 -*-
from cms.exceptions import DontUsePageAttributeWarning
from cms.models.placeholdermodel import Placeholder
from cms.plugin_rendering import PluginContext, PluginRenderer
from cms.plugin_rendering import PluginContext, render_plugin
from cms.utils.helpers import reversion_register
from cms.utils.placeholder import get_page_from_placeholder_if_exists
from datetime import datetime, date
from django.conf import settings
from django.core.exceptions import ValidationError, ObjectDoesNotExist
from django.db import models
from django.db.models.base import ModelBase, model_unpickle, \
simple_class_factory
from django.db.models.base import (ModelBase, model_unpickle,
simple_class_factory)
from django.db.models.query_utils import DeferredAttribute
from django.utils.translation import ugettext_lazy as _
from os.path import join
from mptt.models import MPTTModel, MPTTModelBase
from os.path import join
import warnings

class PluginModelBase(MPTTModelBase):
Expand Down Expand Up @@ -158,8 +158,7 @@ def render_plugin(self, context=None, placeholder=None, admin=False, processors=
raise ValidationError("plugin has no render_template: %s" % plugin.__class__)
else:
template = None
renderer = PluginRenderer(context, instance, placeholder, template, processors)
return renderer.content
return render_plugin(context, instance, placeholder, template, processors)
return ""

def get_media_path(self, filename):
Expand Down
8 changes: 2 additions & 6 deletions cms/plugin_pool.py
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
from cms.exceptions import PluginAlreadyRegistered, PluginNotRegistered
from cms.plugin_base import CMSPluginBase
from cms.utils.django_load import load
from cms.utils.helpers import reversion_register
from cms.utils.placeholder import get_placeholder_conf
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.importlib import import_module

class PluginPool(object):
def __init__(self):
Expand All @@ -16,11 +16,7 @@ def discover_plugins(self):
if self.discovered:
return
self.discovered = True
for app in settings.INSTALLED_APPS:
try:
import_module('.cms_plugins', app)
except ImportError:
pass
load('cms_plugins')

def register_plugin(self, plugin):
"""
Expand Down
21 changes: 21 additions & 0 deletions cms/plugin_processors.py
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
from django.utils.safestring import mark_safe

def plugin_meta_context_processor(instance, placeholder):
return {
'plugin_index': instance._render_meta.index, # deprecated template variable
'plugin': {
'counter': instance._render_meta.index + 1,
'counter0': instance._render_meta.index,
'revcounter': instance._render_meta.total - instance._render_meta.index,
'revcounter0': instance._render_meta.total - instance._render_meta.index - 1,
'first': instance._render_meta.index == 0,
'last': instance._render_meta.index == instance._render_meta.total - 1,
'total': instance._render_meta.total,
'id_attr': 'plugin_%i_%i' % (instance.placeholder.pk, instance.pk),
'instance': instance,
}
}

def mark_safe_plugin_processor(instance, placeholder, rendered_content, original_context):
return mark_safe(rendered_content)
113 changes: 39 additions & 74 deletions cms/plugin_rendering.py
@@ -1,37 +1,17 @@
# -*- coding: utf-8 -*-
from cms import settings
from cms.models.placeholdermodel import Placeholder
from cms.plugin_processors import (plugin_meta_context_processor,
mark_safe_plugin_processor)
from cms.utils import get_language_from_request
from cms.utils.django_load import iterload_objects
from cms.utils.placeholder import (get_page_from_placeholder_if_exists,
get_placeholder_conf)
from django.conf import settings as django_settings
from django.core.exceptions import ImproperlyConfigured
from django.conf import settings
from django.template import Template, Context
from django.template.defaultfilters import title
from django.template.loader import render_to_string
from django.utils.importlib import import_module
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _

def plugin_meta_context_processor(instance, placeholder):
return {
'plugin_index': instance._render_meta.index, # deprecated template variable
'plugin': {
'counter': instance._render_meta.index + 1,
'counter0': instance._render_meta.index,
'revcounter': instance._render_meta.total - instance._render_meta.index,
'revcounter0': instance._render_meta.total - instance._render_meta.index - 1,
'first': instance._render_meta.index == 0,
'last': instance._render_meta.index == instance._render_meta.total - 1,
'total': instance._render_meta.total,
'id_attr': 'plugin_%i_%i' % (instance.placeholder.pk, instance.pk),
'instance': instance,
}
}

def mark_safe_plugin_processor(instance, placeholder, rendered_content, original_context):
return mark_safe(rendered_content)

# these are always called before all other plugin context processors
DEFAULT_PLUGIN_CONTEXT_PROCESSORS = (
plugin_meta_context_processor,
Expand All @@ -42,27 +22,6 @@ def mark_safe_plugin_processor(instance, placeholder, rendered_content, original
mark_safe_plugin_processor,
)

_standard_processors = {}

def get_standard_processors(settings_attr):
global _standard_processors
if not _standard_processors.has_key(settings_attr):
processors = []
if hasattr(django_settings, settings_attr):
for path in getattr(django_settings, settings_attr):
i = path.rfind('.')
module, attr = path[:i], path[i+1:]
try:
mod = import_module(module)
except ImportError, e:
raise ImproperlyConfigured('Error importing plugin context processor module %s: "%s"' % (module, e))
try:
func = getattr(mod, attr)
except AttributeError:
raise ImproperlyConfigured('Module "%s" does not define a "%s" callable plugin context processor' % (module, attr))
processors.append(func)
_standard_processors[settings_attr] = tuple(processors)
return _standard_processors[settings_attr]

class PluginContext(Context):
"""
Expand All @@ -72,34 +31,37 @@ class PluginContext(Context):
using the "processors" keyword argument.
"""
def __init__(self, dict, instance, placeholder, processors=None, current_app=None):
Context.__init__(self, dict, current_app=current_app)
if processors is None:
processors = ()
else:
processors = tuple(processors)
for processor in DEFAULT_PLUGIN_CONTEXT_PROCESSORS + get_standard_processors('CMS_PLUGIN_CONTEXT_PROCESSORS') + processors:
super(PluginContext, self).__init__(dict, current_app=current_app)
if not processors:
processors = []
for processor in DEFAULT_PLUGIN_CONTEXT_PROCESSORS:
self.update(processor(instance, placeholder))

class PluginRenderer(object):
for processor in iterload_objects(settings.CMS_PLUGIN_CONTEXT_PROCESSORS):
self.update(processor(instance, placeholder))
for processor in processors:
self.update(processor(instance, placeholder))

def render_plugin(context, instance, placeholder, template, processors=None,
current_app=None):
"""
This class renders the context to a string using the supplied template.
It then passes the rendered content to all processors defined in
CMS_PLUGIN_PROCESSORS. Additional processors can be specified as a list
of callables using the "processors" keyword argument.
Renders a single plugin and applies the post processors to it's rendered
content.
"""
def __init__(self, context, instance, placeholder, template, processors=None, current_app=None):
if isinstance(template, basestring):
self.content = render_to_string(template, context)
elif isinstance(template, Template):
self.content = template.render(context)
else:
self.content = ''
if processors is None:
processors = ()
else:
processors = tuple(processors)
for processor in get_standard_processors('CMS_PLUGIN_PROCESSORS') + processors + DEFAULT_PLUGIN_PROCESSORS:
self.content = processor(instance, placeholder, self.content, context)
if not processors:
processors = []
if isinstance(template, basestring):
content = render_to_string(template, context)
elif isinstance(template, Template):
content = template.render(context)
else:
content = ''
for processor in iterload_objects(settings.CMS_PLUGIN_PROCESSORS):
content = processor(instance, placeholder, content, context)
for processor in processors:
content = processor(instance, placeholder, content, context)
for processor in DEFAULT_PLUGIN_PROCESSORS:
content = processor(instance, placeholder, content, context)
return content

def render_plugins(plugins, context, placeholder, processors=None):
"""
Expand Down Expand Up @@ -151,10 +113,13 @@ def render_placeholder(placeholder, context_to_copy, name_fallback="Placeholder"

# Prepend frontedit toolbar output if applicable
edit = False
if ("edit" in request.GET or request.session.get("cms_edit", False)) and \
'cms.middleware.toolbar.ToolbarMiddleware' in django_settings.MIDDLEWARE_CLASSES and \
request.user.is_staff and request.user.is_authenticated() and \
(not page or page.has_change_permission(request)):
if (
("edit" in request.GET
or request.session.get("cms_edit", False)
)
and 'cms.middleware.toolbar.ToolbarMiddleware' in settings.MIDDLEWARE_CLASSES
and request.user.is_staff and request.user.is_authenticated()
and (not page or page.has_change_permission(request))):
edit = True
if edit:
from cms.middleware.toolbar import toolbar_plugin_processor
Expand Down
13 changes: 3 additions & 10 deletions cms/tests/apphooks.py
Expand Up @@ -20,13 +20,14 @@ class ApphooksTestCase(CMSTestCase):
def setUp(self):
clear_app_resolvers()
clear_url_caches()

if APP_MODULE in sys.modules:
del sys.modules[APP_MODULE]

def test_01_explicit_apphooks(self):
"""
Test explicit apphook loading with the CMS_APPHOOKS setting.
"""
if APP_MODULE in sys.modules:
del sys.modules[APP_MODULE]
apphooks = (
'%s.%s' % (APP_MODULE, APP_NAME),
)
Expand All @@ -43,8 +44,6 @@ def test_02_implicit_apphooks(self):
"""
Test implicit apphook loading with INSTALLED_APPS + cms_app.py
"""
if APP_MODULE in sys.modules:
del sys.modules[APP_MODULE]

apps = ['project.sampleapp']
with SettingsOverride(INSTALLED_APPS=apps, ROOT_URLCONF='project.urls_for_apphook_tests'):
Expand All @@ -57,9 +56,6 @@ def test_02_implicit_apphooks(self):

def test_03_apphook_on_root(self):

if APP_MODULE in sys.modules:
del sys.modules[APP_MODULE]

with SettingsOverride(ROOT_URLCONF='project.urls_for_apphook_tests'):
apphook_pool.clear()
superuser = User.objects.create_superuser('admin', 'admin@admin.com', 'admin')
Expand All @@ -81,9 +77,6 @@ def test_03_apphook_on_root(self):
apphook_pool.clear()

def test_04_get_page_for_apphook(self):

if APP_MODULE in sys.modules:
del sys.modules[APP_MODULE]

with SettingsOverride(ROOT_URLCONF='project.second_urls_for_apphook_tests'):

Expand Down
4 changes: 2 additions & 2 deletions cms/tests/rendering.py
Expand Up @@ -130,8 +130,8 @@ def test_01_processors(self):
can be defined in settings and are working and that extra plugin context processors can be passed to PluginContext.
"""
with SettingsOverride(
CMS_PLUGIN_PROCESSORS = ('cms.tests.rendering.test_plugin_processor',),
CMS_PLUGIN_CONTEXT_PROCESSORS = ('cms.tests.rendering.test_plugin_context_processor',),
CMS_PLUGIN_PROCESSORS = ('cms.tests.rendering.test_plugin_processor',),
CMS_PLUGIN_CONTEXT_PROCESSORS = ('cms.tests.rendering.test_plugin_context_processor',),
):
def test_passed_plugin_context_processor(instance, placeholder):
return {'test_passed_plugin_context_processor': 'test_passed_plugin_context_processor_ok'}
Expand Down

0 comments on commit 5a595fb

Please sign in to comment.