def test_get_placeholder_conf(self): TEST_CONF = { "main": { "name": "main content", "plugins": ["TextPlugin", "LinkPlugin"], "default_plugins": [{"plugin_type": "TextPlugin", "values": {"body": "<p>Some default text</p>"}}], }, "layout/home.html main": { "name": u"main content with FilerImagePlugin and limit", "plugins": ["TextPlugin", "FilerImagePlugin", "LinkPlugin"], "inherit": "main", "limits": {"global": 1}, }, "layout/other.html main": { "name": u"main content with FilerImagePlugin and no limit", "inherit": "layout/home.html main", "limits": {}, }, } with SettingsOverride(CMS_PLACEHOLDER_CONF=TEST_CONF): # test no inheritance returned = get_placeholder_conf("plugins", "main") self.assertEqual(returned, TEST_CONF["main"]["plugins"]) # test no inherited value with inheritance enabled returned = get_placeholder_conf("plugins", "main", "layout/home.html") self.assertEqual(returned, TEST_CONF["layout/home.html main"]["plugins"]) # test direct inherited value returned = get_placeholder_conf("plugins", "main", "layout/other.html") self.assertEqual(returned, TEST_CONF["layout/home.html main"]["plugins"]) # test grandparent inherited value returned = get_placeholder_conf("default_plugins", "main", "layout/other.html") self.assertEqual(returned, TEST_CONF["main"]["default_plugins"])
def render_placeholder(placeholder, context_to_copy, name_fallback="Placeholder"): """ Renders plugins for a placeholder on the given page using shallow copies of the given context, and returns a string containing the rendered output. """ from cms.plugins.utils import get_plugins context = context_to_copy context.push() request = context['request'] lang = get_language_from_request(request) page = get_page_from_placeholder_if_exists(placeholder) if page: template = page.template else: template = None plugins = [plugin for plugin in get_plugins(request, placeholder, lang)] if (len(plugins)==0 and placeholder and lang != get_default_language() and get_placeholder_conf("language_fallback", placeholder.slot, template, False)): fallbacks = get_fallback_languages(lang) for l in fallbacks: plugins = [plugin for plugin in get_plugins(request, placeholder, l)] if plugins: break # Add extra context as defined in settings, but do not overwrite existing context variables, # since settings are general and database/template are specific # TODO this should actually happen as a plugin context processor, but these currently overwrite # existing context -- maybe change this order? slot = getattr(placeholder, 'slot', None) extra_context = {} if slot: extra_context = get_placeholder_conf("extra_context", slot, template, {}) for key, value in extra_context.items(): if not key in context: context[key] = value content = [] # Prepend frontedit toolbar output if applicable edit = False toolbar = getattr(request, 'toolbar', None) if (getattr(toolbar, 'edit_mode', False) and (not page or page.has_change_permission(request))): edit = True if edit: from cms.middleware.toolbar import toolbar_plugin_processor processors = (toolbar_plugin_processor,) else: processors = None content.extend(render_plugins(plugins, context, placeholder, processors)) content = "".join(content) if edit: content = render_placeholder_toolbar(placeholder, context, content, name_fallback) context.pop() return content
def render_placeholder_toolbar(placeholder, context, content, name_fallback=None): from cms.plugin_pool import plugin_pool request = context["request"] page = get_page_from_placeholder_if_exists(placeholder) if not page: page = getattr(request, "current_page", None) if page: template = page.template if name_fallback and not placeholder: placeholder = Placeholder.objects.create(slot=name_fallback) page.placeholders.add(placeholder) else: template = None if placeholder: slot = placeholder.slot else: slot = None installed_plugins = plugin_pool.get_all_plugins(slot, page) name = get_placeholder_conf(slot, template, "name", title(slot)) name = _(name) toolbar = render_to_string( "cms/toolbar/placeholder.html", { "installed_plugins": installed_plugins, "language": get_language_from_request(request), "placeholder_label": name, "placeholder": placeholder, "page": page, }, ) return "".join([toolbar, content])
def get_all_plugins(self, placeholder=None, page=None, setting_key="plugins", include_page_only=True): from cms.utils.placeholder import get_placeholder_conf self.discover_plugins() self.set_plugin_meta() plugins = sorted(self.plugins.values(), key=attrgetter('name')) template = page and page.get_template() or None allowed_plugins = get_placeholder_conf( setting_key, placeholder, template, ) or () if not include_page_only: # Filters out any plugin marked as page only because # the include_page_only flag has been set to False plugins = (plugin for plugin in plugins if not plugin.page_only) if allowed_plugins: plugins = (plugin for plugin in plugins if plugin.__name__ in allowed_plugins) if placeholder: # Filters out any plugin that requires a parent or has set parent classes plugins = (plugin for plugin in plugins if not plugin.requires_parent_plugin(placeholder, page)) return sorted(plugins, key=attrgetter('module'))
def render_placeholder_toolbar(placeholder, context, content, name_fallback=None): from cms.plugin_pool import plugin_pool request = context['request'] page = get_page_from_placeholder_if_exists(placeholder) if not page: page = getattr(request, 'current_page', None) if page: template = page.template if name_fallback and not placeholder: placeholder = Placeholder.objects.create(slot=name_fallback) page.placeholders.add(placeholder) else: template = None if placeholder: slot = placeholder.slot else: slot = None installed_plugins = plugin_pool.get_all_plugins(slot, page) name = get_placeholder_conf(slot, template, "name", title(slot)) name = _(name) context.push() context.update({ 'installed_plugins': installed_plugins, 'language': get_language_from_request(request), 'placeholder_label': name, 'placeholder': placeholder, 'page': page, }) toolbar = render_to_string("cms/toolbar/placeholder.html", context) context.pop() return "".join([toolbar, content])
def get_all_plugins(self, placeholder=None, page=None, setting_key="plugins", include_page_only=True): self.discover_plugins() self.set_plugin_meta() plugins = list(self.plugins.values()) plugins.sort(key=lambda obj: force_unicode(obj.name)) final_plugins = [] template = page and page.get_template() or None allowed_plugins = get_placeholder_conf( setting_key, placeholder, template, ) or () for plugin in plugins: include_plugin = False if placeholder and not plugin.require_parent: include_plugin = not allowed_plugins and setting_key == "plugins" or plugin.__name__ in allowed_plugins if plugin.page_only and not include_page_only: include_plugin = False if include_plugin: final_plugins.append(plugin) if final_plugins or placeholder: plugins = final_plugins # plugins sorted by modules plugins = sorted(plugins, key=lambda obj: force_unicode(obj.module)) return plugins
def get_label(self): from cms.utils.placeholder import get_placeholder_conf template = self.page.get_template() if self.page else None name = get_placeholder_conf("name", self.slot, template=template, default=title(self.slot)) name = _(name) return name
def get_parent_classes(self, slot, page): template = page and page.get_template() or None ph_conf = get_placeholder_conf('parent_classes', slot, template, default={}) parent_classes = ph_conf.get(self.__class__.__name__, self.parent_classes) if parent_classes is None: return return tuple(parent_classes)
def get_parent_classes(self, slot, page): template = page and page.get_template() or None ph_conf = get_placeholder_conf('parent_classes', slot, template, default={}) parent_classes = ph_conf.get(self.__class__.__name__, self.parent_classes) if parent_classes and isinstance(parent_classes, (list, tuple)): parent_classes = tuple(parent_classes) + tuple(settings.CASCADE_DEFAULT_PARENT_CLASSES) return parent_classes
def get_all_plugins(self, placeholder=None, page=None, setting_key="plugins", include_page_only=True): self.discover_plugins() plugins = self.plugins.values()[:] plugins.sort(key=lambda obj: unicode(obj.name)) final_plugins = [] if page: template = page.get_template() else: template = None allowed_plugins = get_placeholder_conf( setting_key, placeholder, template, ) for plugin in plugins: include_plugin = False if placeholder: if allowed_plugins: if plugin.__name__ in allowed_plugins: include_plugin = True elif setting_key == "plugins": include_plugin = True if plugin.page_only and not include_page_only: include_plugin = False if include_plugin: final_plugins.append(plugin) if final_plugins: plugins = final_plugins # plugins sorted by modules plugins = sorted(plugins, key=lambda obj: unicode(obj.module)) return plugins
def get_parent_classes(self, slot, page): template = page and page.get_template() or None # config overrides.. ph_conf = get_placeholder_conf('parent_classes', slot, template, default={}) parent_classes = ph_conf.get(self.__class__.__name__, self.parent_classes) return parent_classes
def create_default_plugins(request, placeholders, template, lang): """ Create all default plugins for the given ``placeholders`` if they have a "default_plugins" configuration value in settings. return all plugins, children, grandchildren (etc.) created """ from cms.api import add_plugin plugins = list() for placeholder in placeholders: default_plugins = get_placeholder_conf("default_plugins", placeholder.slot, template, None) if not default_plugins: continue if not placeholder.has_add_permission(request): continue for conf in default_plugins: if not permissions.has_plugin_permission( request.user, conf['plugin_type'], "add"): continue plugin = add_plugin(placeholder, conf['plugin_type'], lang, **conf['values']) plugins.append(plugin) if 'children' in conf: children = create_default_children_plugins( request, placeholder, lang, plugin, conf['children']) plugins += children plugin.notify_on_autoadd(request, conf) return plugins
def has_reached_plugin_limit(placeholder, plugin_type, language, template=None): """ Checks if placeholder has reached it's global plugin limit, if not then it checks if it has reached it's plugin_type limit. """ limits = get_placeholder_conf("limits", placeholder.slot, template) if limits: global_limit = limits.get("global") type_limit = limits.get(plugin_type) # total plugin count count = placeholder.get_plugins(language=language).count() if global_limit and count >= global_limit: raise PluginLimitReached( _("This placeholder already has the maximum number of plugins (%s)." % count)) elif type_limit: # total plugin type count type_count = (placeholder.get_plugins(language=language).filter( plugin_type=plugin_type).count()) if type_count >= type_limit: plugin_name = force_text( plugin_pool.get_plugin(plugin_type).name) raise PluginLimitReached(_( "This placeholder already has the maximum number (%(limit)s) of allowed %(plugin_name)s plugins.") \ % {'limit': type_limit, 'plugin_name': plugin_name}) return False
def get_all_plugins(self, placeholder=None, page=None, setting_key="plugins", include_page_only=True): from cms.utils.placeholder import get_placeholder_conf self.discover_plugins() self.set_plugin_meta() plugins = sorted(self.plugins.values(), key=attrgetter('name')) final_plugins = [] template = page and page.get_template() or None allowed_plugins = get_placeholder_conf( setting_key, placeholder, template, ) or () for plugin in plugins: include_plugin = False if placeholder and not plugin.get_require_parent(placeholder, page): include_plugin = not allowed_plugins and setting_key == "plugins" or plugin.__name__ in allowed_plugins if plugin.page_only and not include_page_only: include_plugin = False if include_plugin: final_plugins.append(plugin) if final_plugins or placeholder: plugins = final_plugins return sorted(plugins, key=attrgetter('module'))
def render_placeholder_toolbar(placeholder, context, content, name_fallback=None): from cms.plugin_pool import plugin_pool request = context['request'] page = placeholder.page if placeholder else None if not page: page = getattr(request, 'current_page', None) if page: template = page.template if name_fallback and not placeholder: placeholder = Placeholder.objects.create(slot=name_fallback) page.placeholders.add(placeholder) placeholder.page = page else: template = None if placeholder: slot = placeholder.slot else: slot = None installed_plugins = plugin_pool.get_all_plugins(slot, page) name = get_placeholder_conf("name", slot, template, title(slot)) name = _(name) context.push() context['installed_plugins'] = installed_plugins context['language'] = get_language_from_request(request) context['placeholder_label'] = name context['placeholder'] = placeholder context['page'] = page toolbar = render_to_string("cms/toolbar/placeholder.html", context) context.pop() return "".join([toolbar, content])
def get_label(self): from cms.utils.placeholder import get_placeholder_conf name = get_placeholder_conf("name", self.slot, default=title(self.slot)) name = _(name) return name
def render_placeholder_toolbar(placeholder, context, content, name_fallback=None): from cms.plugin_pool import plugin_pool request = context["request"] page = placeholder.page if placeholder else None if not page: page = getattr(request, "current_page", None) if page: template = page.template if name_fallback and not placeholder: placeholder = Placeholder.objects.create(slot=name_fallback) page.placeholders.add(placeholder) placeholder.page = page else: template = None if placeholder: slot = placeholder.slot else: slot = None installed_plugins = plugin_pool.get_all_plugins(slot, page) name = get_placeholder_conf("name", slot, template, title(slot)) name = _(name) context.push() context["installed_plugins"] = installed_plugins context["language"] = get_language_from_request(request) context["placeholder_label"] = name context["placeholder"] = placeholder context["page"] = page toolbar = render_to_string("cms/toolbar/placeholder.html", context) context.pop() return "".join([toolbar, content])
def has_reached_plugin_limit(placeholder, plugin_type, language, template=None): """ Checks if placeholder has reached it's global plugin limit, if not then it checks if it has reached it's plugin_type limit. """ limits = get_placeholder_conf("limits", placeholder.slot, template) if limits: global_limit = limits.get("global") type_limit = limits.get(plugin_type) # total plugin count count = placeholder.get_plugins(language=language).count() if global_limit and count >= global_limit: raise PluginLimitReached(_("This placeholder already has the maximum number of plugins (%s)." % count)) elif type_limit: # total plugin type count type_count = ( placeholder .get_plugins(language=language) .filter(plugin_type=plugin_type) .count() ) if type_count >= type_limit: plugin_name = force_text(plugin_pool.get_plugin(plugin_type).name) raise PluginLimitReached(_( "This placeholder already has the maximum number (%(limit)s) of allowed %(plugin_name)s plugins.") \ % {'limit': type_limit, 'plugin_name': plugin_name}) return False
def render_placeholder_toolbar(placeholder, context, content, name_fallback=None): from cms.plugin_pool import plugin_pool request = context["request"] page = placeholder.page if placeholder else None if not page: page = getattr(request, "current_page", None) if page: template = page.template if name_fallback and not placeholder: placeholder = Placeholder.objects.create(slot=name_fallback) page.placeholders.add(placeholder) placeholder.page = page else: template = None if placeholder: slot = placeholder.slot else: slot = None # Builds the list of dictionaries containing module, name and value for the plugin dropdowns installed_plugins = get_toolbar_plugin_struct(plugin_pool.get_all_plugins(slot, page), slot, page) name = get_placeholder_conf("name", slot, template, title(slot)) name = _(name) context.push() context["installed_plugins"] = installed_plugins ## to restrict child-only plugins from draggables.. context["allowed_plugins"] = [cls.__name__ for cls in plugin_pool.get_all_plugins(slot, page)] context["language"] = get_language_from_request(request) context["placeholder_label"] = name context["placeholder"] = placeholder context["page"] = page toolbar = render_to_string("cms/toolbar/placeholder_bar.html", context) context.pop() return toolbar
def get_all_plugins(self, placeholder=None, page=None, setting_key="plugins", include_page_only=True): self.discover_plugins() plugins = self.plugins.values()[:] plugins.sort(key=lambda obj: unicode(obj.name)) final_plugins = [] for plugin in plugins: include_plugin = False if placeholder: allowed_plugins = get_placeholder_conf( setting_key, placeholder, getattr(page, 'template', None) ) if allowed_plugins: if plugin.__name__ in allowed_plugins: include_plugin = True elif setting_key == "plugins": include_plugin = True if plugin.page_only and not include_page_only: include_plugin = False if include_plugin: final_plugins.append(plugin) if final_plugins: plugins = final_plugins # plugins sorted by modules plugins = sorted(plugins, key=lambda obj: unicode(obj.module)) return plugins
def assign_plugins(request, placeholders, template=None, lang=None, is_fallback=False): """ Fetch all plugins for the given ``placeholders`` and cast them down to the concrete instances in one query per type. """ if not placeholders: return placeholders = tuple(placeholders) lang = lang or get_language_from_request(request) qs = get_cmsplugin_queryset(request) qs = qs.filter(placeholder__in=placeholders, language=lang) plugins = list(qs.order_by('placeholder', 'path')) fallbacks = defaultdict(list) # If no plugin is present in the current placeholder we loop in the fallback languages # and get the first available set of plugins if (not is_fallback and not (hasattr(request, 'toolbar') and request.toolbar.edit_mode_active)): disjoint_placeholders = (ph for ph in placeholders if all( ph.pk != p.placeholder_id for p in plugins)) for placeholder in disjoint_placeholders: if get_placeholder_conf("language_fallback", placeholder.slot, template, True): for fallback_language in get_fallback_languages(lang): assign_plugins(request, (placeholder, ), template, fallback_language, is_fallback=True) fallback_plugins = placeholder._plugins_cache if fallback_plugins: fallbacks[placeholder.pk] += fallback_plugins break # These placeholders have no fallback non_fallback_phs = [ph for ph in placeholders if ph.pk not in fallbacks] # If no plugin is present in non fallback placeholders, create default plugins if enabled) if not plugins: plugins = create_default_plugins(request, non_fallback_phs, template, lang) plugins = downcast_plugins(plugins, non_fallback_phs, request=request) # split the plugins up by placeholder # Plugins should still be sorted by placeholder plugin_groups = dict( (key, list(plugins)) for key, plugins in groupby(plugins, attrgetter('placeholder_id'))) all_plugins_groups = plugin_groups.copy() for group in plugin_groups: plugin_groups[group] = build_plugin_tree(plugin_groups[group]) groups = fallbacks.copy() groups.update(plugin_groups) for placeholder in placeholders: # This is all the plugins. setattr(placeholder, '_all_plugins_cache', all_plugins_groups.get(placeholder.pk, [])) # This one is only the root plugins. setattr(placeholder, '_plugins_cache', groups.get(placeholder.pk, []))
def assign_plugins(request, placeholders, template, lang=None, no_fallback=False): """ Fetch all plugins for the given ``placeholders`` and cast them down to the concrete instances in one query per type. """ placeholders = list(placeholders) if not placeholders: return lang = lang or get_language_from_request(request) request_lang = lang qs = get_cmsplugin_queryset(request).filter( placeholder__in=placeholders, language=request_lang).order_by('placeholder', 'tree_id', 'level', 'position') plugins = list(qs) # If no plugin is present in the current placeholder we loop in the fallback languages # and get the first available set of plugins if not no_fallback: for placeholder in placeholders: found = False for plugin in plugins: if plugin.placeholder_id == placeholder.pk: found = True break if found: continue elif placeholder and get_placeholder_conf( "language_fallback", placeholder.slot, template, False): if hasattr(request, 'toolbar') and request.toolbar.edit_mode: continue fallbacks = get_fallback_languages(lang) for fallback_language in fallbacks: assign_plugins(request, [placeholder], template, fallback_language, no_fallback=True) fallback_plugins = placeholder._plugins_cache if fallback_plugins: plugins += fallback_plugins break # If no plugin is present, create default plugins if enabled) if not plugins: plugins = create_default_plugins(request, placeholders, template, lang) plugin_list = downcast_plugins(plugins, placeholders) # split the plugins up by placeholder groups = dict((key, list(plugins)) for key, plugins in groupby( plugin_list, operator.attrgetter('placeholder_id'))) for group in groups: groups[group] = build_plugin_tree(groups[group]) for placeholder in placeholders: setattr(placeholder, '_plugins_cache', list(groups.get(placeholder.pk, [])))
def get_require_parent(cls, slot, page): from cms.utils.placeholder import get_placeholder_conf template = page.get_template() if page else None # config overrides.. require_parent = get_placeholder_conf('require_parent', slot, template, default=cls.require_parent) return require_parent
def get_require_parent(cls, slot, page): from cms.utils.placeholder import get_placeholder_conf template = page and page.get_template() or None # config overrides.. require_parent = get_placeholder_conf('require_parent', slot, template, default=cls.require_parent) return require_parent
def get_label(self): from cms.utils.placeholder import get_placeholder_conf if self.page: template = self.page.get_template() else: template = None name = get_placeholder_conf("name", self.slot, template=template, default=title(self.slot)) name = _(name) return name
def get_require_parent(cls, slot, page): template = page and page.get_template() or None # config overrides.. require_parent = get_placeholder_conf('require_parent', slot, template, default=cls.require_parent) return require_parent
def get_parent_classes(cls, slot, page): from cms.utils.placeholder import get_placeholder_conf template = page and page.get_template() or None # config overrides.. ph_conf = get_placeholder_conf('parent_classes', slot, template, default={}) parent_classes = ph_conf.get(cls.__name__, cls.parent_classes) return parent_classes
def get_parent_classes(cls, slot, page, instance=None): from cms.utils.placeholder import get_placeholder_conf template = page.get_template() if page else None # config overrides.. ph_conf = get_placeholder_conf('parent_classes', slot, template, default={}) parent_classes = ph_conf.get(cls.__name__, cls.parent_classes) return parent_classes
def render_placeholder(placeholder, context_to_copy, name_fallback="Placeholder"): """ Renders plugins for a placeholder on the given page using shallow copies of the given context, and returns a string containing the rendered output. """ from cms.plugins.utils import get_plugins context = context_to_copy context.push() request = context['request'] lang = get_language_from_request(request) plugins = [plugin for plugin in get_plugins(request, placeholder)] if not plugins and settings.CMS_LANGUAGE_FALLBACK and lang != get_default_language(): fallbacks = get_fallback_languages(lang) for l in fallbacks: plugins = [plugin for plugin in get_plugins(request, placeholder, l)] if plugins: break page = get_page_from_placeholder_if_exists(placeholder) if page: template = page.template else: template = None # Add extra context as defined in settings, but do not overwrite existing context variables, # since settings are general and database/template are specific # TODO this should actually happen as a plugin context processor, but these currently overwrite # existing context -- maybe change this order? slot = getattr(placeholder, 'slot', None) extra_context = {} if slot: extra_context = get_placeholder_conf("extra_context", slot, template, {}) for key, value in extra_context.items(): if not key in context: context[key] = value c = [] # Prepend frontedit toolbar output if applicable edit = False toolbar = getattr(request, 'toolbar', None) if (getattr(toolbar, 'edit_mode', False) and (not page or page.has_change_permission(request))): edit = True if edit: from cms.middleware.toolbar import toolbar_plugin_processor processors = (toolbar_plugin_processor,) else: processors = None c.extend(render_plugins(plugins, context, placeholder, processors)) content = "".join(c) if edit: content = render_placeholder_toolbar(placeholder, context, content, name_fallback) context.pop() return content
def get_parent_classes(cls, slot, page, instance=None): """Check :method:`cms.plugin_base.CMSPluginBase.get_parent_classes` for details""" from cms.utils.placeholder import get_placeholder_conf template = page and page.get_template() or None # config overrides.. ph_conf = get_placeholder_conf('parent_classes', slot, template, default={}) parent_classes = ph_conf.get(cls.__name__, cls.parent_classes) return parent_classes
def get_child_classes(self, slot, page): template = page and page.get_template() or None # config overrides.. ph_conf = get_placeholder_conf('child_classes', slot, template, default={}) child_classes = ph_conf.get(self.__class__.__name__, self.child_classes) if child_classes: return child_classes from cms.plugin_pool import plugin_pool installed_plugins = plugin_pool.get_all_plugins(slot, page) return [cls.__name__ for cls in installed_plugins]
def get_child_classes(self, slot, page): if self.cms_plugin_instance: if self.cms_plugin_instance.parent: plugin_class = self.cms_plugin_instance.parent.get_plugin_class() child_classes = plugin_class().get_child_classes(slot, page) else: # SegmentPlugin is at the root level template = page and page.get_template() or None child_classes = get_placeholder_conf('plugins', slot, template, default=[]) else: child_classes = super(SegmentPlugin, self).get_child_classes(slot, page) return child_classes
def get_parent_glossary(self): """ Return the glossary from the parent of this object. """ parent = self.get_parent() if parent: return parent.get_complete_glossary() else: # use self.placeholder.glossary as the starting dictionary template = self.placeholder.page and self.placeholder.page.template or None return get_placeholder_conf('glossary', self.placeholder.slot, template=template, default={})
def get_parent_glossary(self): """ Return the glossary from the parent of this object. If there is no parent, retrieve the glossary from the placeholder settings, if configured. """ parent = self.get_parent_instance() if parent: return parent.get_complete_glossary() # otherwise use self.placeholder.glossary as the starting dictionary template = self.placeholder.page.template if self.placeholder.page else None return get_placeholder_conf('glossary', self.placeholder.slot, template=template, default={})
def get_child_class_overrides(cls, slot, page): """ Returns a list of plugin types that are allowed as children of this plugin. """ from cms.utils.placeholder import get_placeholder_conf template = page.get_template() if page else None # config overrides.. ph_conf = get_placeholder_conf('child_classes', slot, template, default={}) return ph_conf.get(cls.__name__, cls.child_classes)
def get_parent_classes(self, slot, page): template = page and page.get_template() or None ph_conf = get_placeholder_conf('parent_classes', slot, template, default={}) parent_classes = ph_conf.get(self.__class__.__name__, self.parent_classes) if parent_classes is None: return # allow all parent classes which inherit from TransparentMixin parent_classes = set(parent_classes) for p in plugin_pool.get_all_plugins(): if self.allow_children and issubclass(p, TransparentMixin): parent_classes.add(p.__name__) return tuple(parent_classes)
def render_placeholder(placeholder, context_to_copy, name_fallback="Placeholder"): """ Renders plugins for a placeholder on the given page using shallow copies of the given context, and returns a string containing the rendered output. """ from cms.plugins.utils import get_plugins context = context_to_copy context.push() request = context["request"] plugins = [plugin for plugin in get_plugins(request, placeholder)] page = get_page_from_placeholder_if_exists(placeholder) if page: template = page.template else: template = None # Add extra context as defined in settings, but do not overwrite existing context variables, # since settings are general and database/template are specific # TODO this should actually happen as a plugin context processor, but these currently overwrite # existing context -- maybe change this order? slot = getattr(placeholder, "slot", None) extra_context = {} if slot: extra_context = get_placeholder_conf("extra_context", slot, template, {}) for key, value in extra_context.items(): if not key in context: context[key] = value c = [] # 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 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 processors = (toolbar_plugin_processor,) else: processors = None c.extend(render_plugins(plugins, context, placeholder, processors)) content = "".join(c) if edit: content = render_placeholder_toolbar(placeholder, context, content, name_fallback) context.pop() return content
def get_child_class_overrides(cls, slot, page): """ Returns a list of plugin types that are allowed as children of this plugin. """ from cms.utils.placeholder import get_placeholder_conf template = page and page.get_template() or None # config overrides.. ph_conf = get_placeholder_conf('child_classes', slot, template, default={}) return ph_conf.get(cls.__name__, cls.child_classes)
def test_get_placeholder_conf(self): TEST_CONF = { 'main': { 'name': 'main content', 'plugins': ['TextPlugin', 'LinkPlugin'], 'default_plugins':[ { 'plugin_type':'TextPlugin', 'values':{ 'body':'<p>Some default text</p>' }, }, ], }, 'layout/home.html main': { 'name': u'main content with FilerImagePlugin and limit', 'plugins': ['TextPlugin', 'FilerImagePlugin', 'LinkPlugin',], 'inherit':'main', 'limits': {'global': 1,}, }, 'layout/other.html main': { 'name': u'main content with FilerImagePlugin and no limit', 'inherit':'layout/home.html main', 'limits': {}, }, } with SettingsOverride(CMS_PLACEHOLDER_CONF=TEST_CONF): #test no inheritance returned = get_placeholder_conf('plugins', 'main') self.assertEqual(returned, TEST_CONF['main']['plugins']) #test no inherited value with inheritance enabled returned = get_placeholder_conf('plugins', 'main', 'layout/home.html') self.assertEqual(returned, TEST_CONF['layout/home.html main']['plugins']) #test direct inherited value returned = get_placeholder_conf('plugins', 'main', 'layout/other.html') self.assertEqual(returned, TEST_CONF['layout/home.html main']['plugins']) #test grandparent inherited value returned = get_placeholder_conf('default_plugins', 'main', 'layout/other.html') self.assertEqual(returned, TEST_CONF['main']['default_plugins'])
def get_parent_classes(self, slot, page): template = None if page: template = page.template # config overrides.. ph_conf = get_placeholder_conf('parent_classes', slot, template, default={}) parent_classes = ph_conf.get(self.__class__.__name__, None) if parent_classes is not None: return parent_classes elif self.parent_classes: return self.parent_classes else: return None
def get_child_classes(self, slot, page): if not hasattr(self, '_cached_child_classes'): if self.cms_plugin_instance: if self.cms_plugin_instance.parent: parent_plugin_instance, parent_plugin = self.cms_plugin_instance.parent.get_plugin_instance() parent_plugin.cms_plugin_instance = parent_plugin_instance child_classes = set(parent_plugin.get_child_classes(slot, page)) else: # SegmentPlugin is at the root level template = page and page.get_template() or None child_classes = set(get_placeholder_conf('plugins', slot, template, default=[])) else: child_classes = set() child_classes.update(super(TransparentMixin, self).get_child_classes(slot, page)) self._cached_child_classes = tuple(child_classes) return self._cached_child_classes
def get_parent_glossary(self): """ Return the glossary from the parent of this object. If there is no parent, retrieve the glossary from the placeholder settings, if configured. """ for model in CascadeModelBase._get_cascade_elements(): try: parent = model.objects.get(id=self.parent_id) except model.DoesNotExist: continue else: return parent.get_complete_glossary() # use self.placeholder.glossary as the starting dictionary template = self.placeholder.page.template if self.placeholder.page else None return get_placeholder_conf('glossary', self.placeholder.slot, template=template, default={})
def get_parent_glossary(self): """ Return the glossary from the parent of this object. If there is no parent, retrieve the glossary from the placeholder settings, if configured. """ for model in CascadeModelBase._get_cascade_elements(): try: parent = model.objects.get(id=self.parent_id) except model.DoesNotExist: continue else: return parent.get_complete_glossary() # use self.placeholder.glossary as the starting dictionary template = self.placeholder.page.template if self.placeholder.page else None return get_placeholder_conf("glossary", self.placeholder.slot, template=template, default={})
def get_child_classes(self, slot, page): if self.cms_plugin_instance: if self.cms_plugin_instance.parent: plugin_class = self.cms_plugin_instance.parent.get_plugin_class( ) child_classes = plugin_class().get_child_classes(slot, page) else: # SegmentPlugin is at the root level template = page and page.get_template() or None child_classes = get_placeholder_conf('plugins', slot, template, default=[]) else: child_classes = super(SegmentPlugin, self).get_child_classes(slot, page) return child_classes
def get_child_classes(self, slot, page): template = None if page: template = page.template # config overrides.. ph_conf = get_placeholder_conf('child_classes', slot, template, default={}) child_classes = ph_conf.get(self.__class__.__name__, None) if child_classes is not None: return child_classes if self.child_classes: return self.child_classes else: from cms.plugin_pool import plugin_pool installed_plugins = plugin_pool.get_all_plugins(slot, page) return [cls.__name__ for cls in installed_plugins]
def assign_plugins(request, placeholders, template, lang=None, is_fallback=False): """ Fetch all plugins for the given ``placeholders`` and cast them down to the concrete instances in one query per type. """ if not placeholders: return placeholders = tuple(placeholders) lang = lang or get_language_from_request(request) qs = get_cmsplugin_queryset(request) qs = qs.filter(placeholder__in=placeholders, language=lang) plugins = list(qs.order_by('placeholder', 'path')) # If no plugin is present in the current placeholder we loop in the fallback languages # and get the first available set of plugins if (not is_fallback and not (hasattr(request, 'toolbar') and request.toolbar.edit_mode)): disjoint_placeholders = (ph for ph in placeholders if all( ph.pk != p.placeholder_id for p in plugins)) for placeholder in disjoint_placeholders: if get_placeholder_conf("language_fallback", placeholder.slot, template, True): for fallback_language in get_fallback_languages(lang): assign_plugins(request, (placeholder, ), template, fallback_language, is_fallback=True) fallback_plugins = placeholder._plugins_cache if fallback_plugins: plugins += fallback_plugins break # If no plugin is present, create default plugins if enabled) if not plugins: plugins = create_default_plugins(request, placeholders, template, lang) plugins = downcast_plugins(plugins, placeholders) # split the plugins up by placeholder # Plugins should still be sorted by placeholder groups = dict((ph_id, build_plugin_tree(ph_plugins)) for ph_id, ph_plugins in groupby( plugins, attrgetter('placeholder_id'))) for placeholder in placeholders: setattr(placeholder, '_plugins_cache', groups.get(placeholder.pk, []))