Permalink
Newer
Older
100644 163 lines (149 sloc) 6.19 KB
1
# -*- coding: utf-8 -*-
2
from cms.models.placeholdermodel import Placeholder
3
from cms.plugin_processors import (plugin_meta_context_processor,
4
mark_safe_plugin_processor)
5
from cms.utils import get_language_from_request
6
from cms.utils.django_load import iterload_objects
7
from cms.utils.placeholder import (get_page_from_placeholder_if_exists,
8
get_placeholder_conf)
9
from django.conf import settings
Aug 12, 2010
10
from django.template import Template, Context
11
from django.template.defaultfilters import title
12
from django.template.loader import render_to_string
13
from django.utils.translation import ugettext_lazy as _
15
# these are always called before all other plugin context processors
16
DEFAULT_PLUGIN_CONTEXT_PROCESSORS = (
20
# these are always called after all other plugin processors
21
DEFAULT_PLUGIN_PROCESSORS = (
22
mark_safe_plugin_processor,
23
)
Aug 12, 2010
26
class PluginContext(Context):
27
"""
28
This subclass of template.Context automatically populates itself using
29
the processors defined in CMS_PLUGIN_CONTEXT_PROCESSORS.
30
Additional processors can be specified as a list of callables
31
using the "processors" keyword argument.
32
"""
33
def __init__(self, dict, instance, placeholder, processors=None, current_app=None):
34
super(PluginContext, self).__init__(dict, current_app=current_app)
35
if not processors:
36
processors = []
37
for processor in DEFAULT_PLUGIN_CONTEXT_PROCESSORS:
Aug 12, 2010
38
self.update(processor(instance, placeholder))
39
for processor in iterload_objects(settings.CMS_PLUGIN_CONTEXT_PROCESSORS):
40
self.update(processor(instance, placeholder))
41
for processor in processors:
42
self.update(processor(instance, placeholder))
43
44
def render_plugin(context, instance, placeholder, template, processors=None,
45
current_app=None):
47
Renders a single plugin and applies the post processors to it's rendered
48
content.
50
if not processors:
51
processors = []
52
if isinstance(template, basestring):
53
content = render_to_string(template, context)
54
elif isinstance(template, Template):
55
content = template.render(context)
56
else:
57
content = ''
58
for processor in iterload_objects(settings.CMS_PLUGIN_PROCESSORS):
59
content = processor(instance, placeholder, content, context)
60
for processor in processors:
61
content = processor(instance, placeholder, content, context)
62
for processor in DEFAULT_PLUGIN_PROCESSORS:
63
content = processor(instance, placeholder, content, context)
64
return content
66
def render_plugins(plugins, context, placeholder, processors=None):
67
"""
68
Renders a collection of plugins with the given context, using the appropriate processors
69
for a given placeholder name, and returns a list containing a "rendered content" string
70
for each plugin.
71
72
This is the main plugin rendering utility function, use this function rather than
73
Plugin.render_plugin().
74
"""
75
c = []
76
total = len(plugins)
77
for index, plugin in enumerate(plugins):
78
plugin._render_meta.total = total
79
plugin._render_meta.index = index
80
context.push()
81
c.append(plugin.render_plugin(context, placeholder, processors=processors))
82
context.pop()
85
def render_placeholder(placeholder, context_to_copy, name_fallback="Placeholder"):
86
"""
87
Renders plugins for a placeholder on the given page using shallow copies of the
88
given context, and returns a string containing the rendered output.
89
"""
90
from cms.plugins.utils import get_plugins
93
request = context['request']
94
plugins = [plugin for plugin in get_plugins(request, placeholder)]
95
page = get_page_from_placeholder_if_exists(placeholder)
96
if page:
97
template = page.template
98
else:
99
template = None
100
# Add extra context as defined in settings, but do not overwrite existing context variables,
101
# since settings are general and database/template are specific
102
# TODO this should actually happen as a plugin context processor, but these currently overwrite
103
# existing context -- maybe change this order?
Nov 22, 2010
104
slot = getattr(placeholder, 'slot', None)
105
extra_context = {}
106
if slot:
107
extra_context = get_placeholder_conf("extra_context", slot, template, {})
108
for key, value in extra_context.items():
109
if not key in context:
110
context[key] = value
111
112
c = []
113
114
# Prepend frontedit toolbar output if applicable
115
edit = False
Jun 8, 2011
116
toolbar = getattr(request, 'toolbar', None)
117
118
if (getattr(toolbar, 'edit_mode', False) and
119
(not page or page.has_change_permission(request))):
120
edit = True
121
if edit:
122
from cms.middleware.toolbar import toolbar_plugin_processor
123
processors = (toolbar_plugin_processor,)
124
else:
125
processors = None
126
127
c.extend(render_plugins(plugins, context, placeholder, processors))
128
content = "".join(c)
129
if edit:
130
content = render_placeholder_toolbar(placeholder, context, content, name_fallback)
134
def render_placeholder_toolbar(placeholder, context, content, name_fallback=None):
135
from cms.plugin_pool import plugin_pool
136
request = context['request']
137
page = get_page_from_placeholder_if_exists(placeholder)
138
if not page:
139
page = getattr(request, 'current_page', None)
140
if page:
141
template = page.template
142
if name_fallback and not placeholder:
143
placeholder = Placeholder.objects.create(slot=name_fallback)
144
page.placeholders.add(placeholder)
147
if placeholder:
148
slot = placeholder.slot
149
else:
150
slot = None
151
installed_plugins = plugin_pool.get_all_plugins(slot, page)
@yakky
Fix for issue #1200 as reported in pull request.
Jun 7, 2012
152
name = get_placeholder_conf("name", slot, template, title(slot))
154
context.push()
155
context['installed_plugins'] = installed_plugins
156
context['language'] = get_language_from_request(request)
157
context['placeholder_label'] = name
158
context['placeholder'] = placeholder
159
context['page'] = page
160
toolbar = render_to_string("cms/toolbar/placeholder.html", context)
Make @FinalAngel happy by allowing sekizai to be used in placeholder.…
Jun 28, 2011
161
context.pop()
162
return "".join([toolbar, content])