def test_render_placeholder_cache(self): """ Regression test for #4223 Assert that placeholder cache is cleared correctly when a plugin is saved """ invalidate_cms_page_cache() ex = Example1(char_1='one', char_2='two', char_3='tree', char_4='four') ex.save() ph1 = ex.placeholder ### # add the test plugin ## test_plugin = add_plugin(ph1, u"TextPlugin", u"en", body="Some text") test_plugin.save() # asserting initial text context = SekizaiContext() context['request'] = self.get_request() text = render_placeholder(ph1, context) self.assertEqual(text, "Some text") # deleting local plugin cache del ph1._plugins_cache test_plugin.body = 'Other text' test_plugin.save() # plugin text has changed, so the placeholder rendering text = render_placeholder(ph1, context) self.assertEqual(text, "Other text")
def test_render(self): page = create_page(title='hellp', template='page.html', language='en') request = self.get_request(page, 'en') plugin = add_plugin(page.placeholders.get(slot='content'), 'LinkPlugin', 'en', url='http://example.com', name='some text') context = PluginContext({'request': request}, plugin, page.placeholders.get(slot='content')) output = render_placeholder(page.placeholders.get(slot='content'), context, editable=False) self.assertEqual(output, '<a href="http://example.com">some text</a>') plugin.delete() plugin = add_plugin(page.placeholders.get(slot='content'), 'LinkPlugin', 'en', url='http://example.com') add_plugin(page.placeholders.get(slot='content'), 'TextPlugin', 'en', body='text body', target=plugin) output = render_placeholder(page.placeholders.get(slot='content'), context, editable=False) self.assertEqual( output, '<span class="plugin_link"><a href="http://example.com">text body</a></span>' )
def get_content(self, request, current_page, context): pages = [current_page] if self.inherit: pages = chain([current_page], current_page.get_cached_ancestors(ascending=True)) for page in pages: template = get_template_from_request(request, page) placeholder = self._get_placeholder(current_page, page, context, self.name) if placeholder is None: continue if not get_plugins(request, placeholder): continue if hasattr(request, 'placeholder_media'): request.placeholder_media = reduce(operator.add, [ request.placeholder_media, placeholder.get_media(request, context) ]) #request.placeholder_media += placeholder.get_media(request, context) content = render_placeholder(placeholder, context) if content: return content, placeholder placeholder = self._get_placeholder(current_page, current_page, context, self.name) content = render_placeholder(placeholder, context) return content, placeholder
def get_placeholder_content(context, request, current_page, name, inherit, default): from django.core.cache import cache edit_mode = getattr(request, 'toolbar', None) and getattr( request.toolbar, 'edit_mode') pages = [current_page] # don't display inherited plugins in edit mode, so that the user doesn't # mistakenly edit/delete them. This is a fix for issue #1303. See the discussion # there for possible enhancements if inherit and not edit_mode: pages = chain([current_page], current_page.get_cached_ancestors(ascending=True)) for page in pages: placeholder = _get_placeholder(current_page, page, context, name) if placeholder is None: continue if not edit_mode and get_cms_setting('PLACEHOLDER_CACHE'): if hasattr(placeholder, 'content_cache'): return mark_safe(placeholder.content_cache) if not hasattr(placeholder, 'cache_checked'): cache_key = placeholder.get_cache_key(get_language()) cached_value = cache.get(cache_key) if not cached_value is None: restore_sekizai_context(context, cached_value['sekizai']) return mark_safe(cached_value['content']) if not get_plugins(request, placeholder, page.get_template()): continue content = render_placeholder(placeholder, context, name) if content: return content # if we reach this point, we have an empty or non-existant placeholder # call _get_placeholder again to get the placeholder properly rendered # in frontend editing placeholder = _get_placeholder(current_page, current_page, context, name) return render_placeholder(placeholder, context, name, default=default)
def get_placeholder_content(context, request, current_page, name, inherit): edit_mode = getattr(request, 'toolbar', None) and getattr(request.toolbar, 'edit_mode') pages = [current_page] # don't display inherited plugins in edit mode, so that the user doesn't # mistakenly edit/delete them. This is a fix for issue #1303. See the discussion # there for possible enhancements if inherit and not edit_mode: pages = chain([current_page], current_page.get_cached_ancestors(ascending=True)) for page in pages: placeholder = _get_placeholder(current_page, page, context, name) if placeholder is None: continue if not get_plugins(request, placeholder): continue # @modified wej # ToDo: Add snippet processing logic content = render_placeholder(placeholder, context, name) if content: return content # if we reach this point, we have an empty or non-existant placeholder # call _get_placeholder again to get the placeholder properly rendered # in frontend editing placeholder = _get_placeholder(current_page, current_page, context, name) return render_placeholder(placeholder, context, name)
def get_placeholder_content(context, request, current_page, name, inherit, default): edit_mode = getattr(request, 'toolbar', None) and getattr(request.toolbar, 'edit_mode') pages = [current_page] # don't display inherited plugins in edit mode, so that the user doesn't # mistakenly edit/delete them. This is a fix for issue #1303. See the discussion # there for possible enhancements if inherit and not edit_mode: pages = chain([current_page], list(reversed(current_page.get_cached_ancestors()))) for page in pages: placeholder = _get_placeholder(current_page, page, context, name) if placeholder is None: continue if not edit_mode and get_cms_setting('PLACEHOLDER_CACHE'): if hasattr(placeholder, 'content_cache'): return mark_safe(placeholder.content_cache) if not hasattr(placeholder, 'cache_checked'): cached_value = get_placeholder_cache(placeholder, get_language()) if cached_value is not None: restore_sekizai_context(context, cached_value['sekizai']) return mark_safe(cached_value['content']) if not get_plugins(request, placeholder, page.get_template()): continue content = render_placeholder(placeholder, context, name) if content: return content # if we reach this point, we have an empty or non-existant placeholder # call _get_placeholder again to get the placeholder properly rendered # in frontend editing placeholder = _get_placeholder(current_page, current_page, context, name) return render_placeholder(placeholder, context, name, default=default)
def test_render_placeholder_cache(self): """ Regression test for #4223 Assert that placeholder cache is cleared correctly when a plugin is saved """ invalidate_cms_page_cache() ex = Example1(char_1="one", char_2="two", char_3="tree", char_4="four") ex.save() ph1 = ex.placeholder ### # add the test plugin ## test_plugin = add_plugin(ph1, u"TextPlugin", u"en", body="Some text") test_plugin.save() # asserting initial text context = SekizaiContext() context["request"] = self.get_request() text = render_placeholder(ph1, context) self.assertEqual(text, "Some text") # deleting local plugin cache del ph1._plugins_cache test_plugin.body = "Other text" test_plugin.save() # plugin text has changed, so the placeholder rendering text = render_placeholder(ph1, context) self.assertEqual(text, "Other text")
def test_plugins_language_fallback(self): """ Tests language_fallback placeholder configuration """ page_en = create_page('page_en', 'col_two.html', 'en') title_de = create_title("de", "page_de", page_en) placeholder_en = page_en.placeholders.get(slot='col_left') placeholder_de = title_de.page.placeholders.get(slot='col_left') add_plugin(placeholder_en, TextPlugin, 'en', body='en body') class NoPushPopContext(SekizaiContext): def push(self): pass pop = push context_en = NoPushPopContext() context_en['request'] = self.get_request(language="en", page=page_en) context_de = NoPushPopContext() context_de['request'] = self.get_request(language="de", page=page_en) # First test the default (non-fallback) behavior) ## English page should have the text plugin content_en = render_placeholder(placeholder_en, context_en) self.assertRegexpMatches(content_en, "^en body$") ## Deutsch page should have no text content_de = render_placeholder(placeholder_de, context_de) self.assertNotRegex(content_de, "^en body$") self.assertEqual(len(content_de), 0) conf = { 'col_left': { 'language_fallback': True, }, } with SettingsOverride(CMS_PLACEHOLDER_CONF=conf): ## Deutsch page should have no text del(placeholder_de._plugins_cache) cache.clear() content_de = render_placeholder(placeholder_de, context_de) self.assertRegexpMatches(content_de, "^en body$") context_de2 = NoPushPopContext() request = self.get_request(language="de", page=page_en) request.user = self.get_superuser() request.toolbar = CMSToolbar(request) request.toolbar.edit_mode = True context_de2['request'] = request del(placeholder_de._plugins_cache) cache.clear() content_de2 = render_placeholder(placeholder_de, context_de2) self.assertFalse("en body" in content_de2) # remove the cached plugins instances del(placeholder_de._plugins_cache) cache.clear() # Then we add a plugin to check for proper rendering add_plugin(placeholder_de, TextPlugin, 'de', body='de body') content_de = render_placeholder(placeholder_de, context_de) self.assertRegexpMatches(content_de, "^de body$")
def test_plugins_children_prepopulate(self): """ Validate a default textplugin with a nested default link plugin """ class NoPushPopContext(Context): def push(self): pass pop = push conf = { 'col_left': { 'default_plugins': [ { 'plugin_type': 'TextPlugin', 'values': { 'body': '<p>body %(_tag_child_1)s and %(_tag_child_2)s</p>' }, 'children': [ { 'plugin_type': 'LinkPlugin', 'values': { 'name': 'django', 'url': 'https://www.djangoproject.com/' }, }, { 'plugin_type': 'LinkPlugin', 'values': { 'name': 'django-cms', 'url': 'https://www.django-cms.org' }, }, ] }, ] }, } with SettingsOverride(CMS_PLACEHOLDER_CONF=conf): page = create_page('page_en', 'col_two.html', 'en') placeholder = page.placeholders.get(slot='col_left') context = NoPushPopContext() context['request'] = self.get_request(language="en", page=page) render_placeholder(placeholder, context) plugins = placeholder.get_plugins_list() self.assertEqual(len(plugins), 3) self.assertEqual(plugins[0].plugin_type, 'TextPlugin') self.assertEqual(plugins[1].plugin_type, 'LinkPlugin') self.assertEqual(plugins[2].plugin_type, 'LinkPlugin') self.assertTrue(plugins[1].parent == plugins[2].parent and plugins[1].parent == plugins[0])
def get_placeholder_content(context, request, current_page, name, inherit): pages = [current_page] if inherit: pages = chain([current_page], current_page.get_cached_ancestors(ascending=True)) for page in pages: placeholder = _get_placeholder(current_page, page, context, name) if placeholder is None: continue if not get_plugins(request, placeholder): continue content = render_placeholder(placeholder, context, name) if content: return content placeholder = _get_placeholder(current_page, current_page, context, name) return render_placeholder(placeholder, context, name)
def test_render(self): page = create_page(title='hellp', template='page.html', language='en') request = self.get_request(page, 'en') plugin = add_plugin(page.placeholders.get(slot='content'), 'LinkPlugin', 'en', url='http://example.com', name='some text') context = PluginContext({'request': request}, plugin, page.placeholders.get(slot='content')) output = render_placeholder(page.placeholders.get(slot='content'), context, editable=False) self.assertEqual(output, '<a href="http://example.com">some text</a>') plugin.delete() plugin = add_plugin(page.placeholders.get(slot='content'), 'LinkPlugin', 'en', url='http://example.com') add_plugin(page.placeholders.get(slot='content'), 'TextPlugin', 'en', body='text body', target=plugin) output = render_placeholder(page.placeholders.get(slot='content'), context, editable=False) self.assertEqual(output, '<span class="plugin_link"><a href="http://example.com">text body</a></span>')
def test_plugins_prepopulate(self): """ Tests prepopulate placeholder configuration """ class NoPushPopContext(Context): def push(self): pass pop = push conf = { 'col_left': { 'default_plugins' : [ { 'plugin_type':'TextPlugin', 'values':{'body':'<p>en default body 1</p>'}, }, { 'plugin_type':'TextPlugin', 'values':{'body':'<p>en default body 2</p>'}, }, ] }, } with SettingsOverride(CMS_PLACEHOLDER_CONF=conf): page = create_page('page_en', 'col_two.html', 'en') placeholder = page.placeholders.get(slot='col_left') context = NoPushPopContext() context['request'] = self.get_request(language="en", page=page) # Our page should have "en default body 1" AND "en default body 2" content = render_placeholder(placeholder, context) self.assertRegexpMatches(content, "^<p>en default body 1</p>\s*<p>en default body 2</p>$")
def test_placeholder_context_leaking(self): TEST_CONF = {'test': {'extra_context': {'width': 10}}} ph = Placeholder.objects.create(slot='test') class NoPushPopContext(Context): def push(self): pass pop = push context = NoPushPopContext() context['request'] = self.get_request() with SettingsOverride(CMS_PLACEHOLDER_CONF=TEST_CONF): render_placeholder(ph, context) self.assertTrue('width' in context) self.assertEqual(context['width'], 10) ph.render(context, None) self.assertTrue('width' in context) self.assertEqual(context['width'], 10)
def _show_placeholder_for_page(context, placeholder_name, page_lookup, lang=None, site=None, cache_result=True): """ Shows the content of a page with a placeholder name and given lookup arguments in the given language. This is useful if you want to have some more or less static content that is shared among many pages, such as a footer. See _get_page_by_untyped_arg() for detailed information on the allowed types and their interpretation for the page_lookup argument. """ cache_result = False validate_placeholder_name(placeholder_name) request = context.get('request', False) site_id = get_site_id(site) if not request: return {'content': ''} if lang is None: lang = get_language_from_request(request) if cache_result: base_key = _get_cache_key('_show_placeholder_for_page', page_lookup, lang, site_id) cache_key = _clean_key('%s_placeholder:%s' % (base_key, placeholder_name)) cached_value = cache.get(cache_key) if isinstance(cached_value, dict): # new style _restore_sekizai(context, cached_value['sekizai']) return {'content': mark_safe(cached_value['content'])} elif isinstance(cached_value, basestring): # old style return {'content': mark_safe(cached_value)} page = _get_page_by_untyped_arg(page_lookup, request, site_id) if not page: return {'content': ''} try: placeholder = page.placeholders.get(slot=placeholder_name) except PlaceholderModel.DoesNotExist: if settings.DEBUG: raise return {'content': ''} watcher = Watcher(context) content = render_placeholder(placeholder, context, placeholder_name) changes = watcher.get_changes() if cache_result: cache.set(cache_key, { 'content': content, 'sekizai': changes }, get_cms_setting('CACHE_DURATIONS')['content']) if content: return {'content': mark_safe(content.strip())} return {'content': ''}
def test_plugins_prepopulate(self): """ Tests prepopulate placeholder configuration """ class NoPushPopContext(Context): def push(self): pass pop = push conf = { "col_left": { "default_plugins": [ {"plugin_type": "TextPlugin", "values": {"body": "<p>en default body 1</p>"}}, {"plugin_type": "TextPlugin", "values": {"body": "<p>en default body 2</p>"}}, ] } } with SettingsOverride(CMS_PLACEHOLDER_CONF=conf): page = create_page("page_en", "col_two.html", "en") placeholder = page.placeholders.get(slot="col_left") context = NoPushPopContext() context["request"] = self.get_request(language="en", page=page) # Our page should have "en default body 1" AND "en default body 2" content = render_placeholder(placeholder, context) self.assertRegexpMatches(content, "^<p>en default body 1</p>\s*<p>en default body 2</p>$")
def test_plugins_discarded_with_language_fallback(self): """ Tests side effect of language fallback: if fallback enabled placeholder existed, it discards all other existing plugins """ page_en = create_page("page_en", "col_two.html", "en") create_title("de", "page_de", page_en) placeholder_sidebar_en = page_en.placeholders.get(slot="col_sidebar") placeholder_en = page_en.placeholders.get(slot="col_left") add_plugin(placeholder_sidebar_en, TextPlugin, "en", body="en body") class NoPushPopContext(Context): def push(self): pass pop = push context_en = NoPushPopContext() context_en["request"] = self.get_request(language="en", page=page_en) conf = {"col_left": {"language_fallback": True}} with SettingsOverride(CMS_PLACEHOLDER_CONF=conf): # call assign plugins first, as this is what is done in real cms life # for all placeholders in a page at once assign_plugins(context_en["request"], [placeholder_sidebar_en, placeholder_en], "col_two.html") # if the normal, non fallback enabled placeholder still has content content_en = render_placeholder(placeholder_sidebar_en, context_en) self.assertRegexpMatches(content_en, "^en body$") # remove the cached plugins instances del (placeholder_sidebar_en._plugins_cache) cache.clear()
def render_tag(self, context, code, extra_bits, nodelist=None): # TODO: language override (the reason this is not implemented, is that language selection is buried way # down somewhere in some method called in render_plugins. There it gets extracted from the request # and a language in request.GET always overrides everything.) if not code: # an empty string was passed in or the variable is not available in the context if nodelist: return nodelist.render(context) return '' request = context.get('request', False) if not request: if nodelist: return nodelist.render(context) return '' if isinstance(code, StaticPlaceholder): static_placeholder = code else: if 'site' in extra_bits: site = Site.objects.get_current() static_placeholder, __ = StaticPlaceholder.objects.get_or_create(code=code, site_id=site.pk, defaults={'name': code, 'creation_method': StaticPlaceholder.CREATION_BY_TEMPLATE}) else: static_placeholder, __ = StaticPlaceholder.objects.get_or_create(code=code, site_id__isnull=True, defaults={'name': code, 'creation_method': StaticPlaceholder.CREATION_BY_TEMPLATE}) if not hasattr(request, 'static_placeholders'): request.static_placeholders = [] request.static_placeholders.append(static_placeholder) if hasattr(request, 'toolbar') and request.toolbar.edit_mode: placeholder = static_placeholder.draft else: placeholder = static_placeholder.public placeholder.is_static = True content = render_placeholder(placeholder, context, name_fallback=code, default=nodelist) return content
def html_content(self): """ Render the content_placeholder field dynamicly. https://github.com/Fantomas42/cmsplugin-zinnia/issues/3 """ context = self.acquire_context() return render_placeholder(self.content_placeholder, context)
def save_model(self, request, nodetype, form, change): """Fill the content field with the interpretation of the placeholder""" context = RequestContext(request) nodetype.content = render_placeholder(nodetype.content_placeholder, context) super(NodetypePlaceholderAdmin, self).save_model( request, nodetype, form, change)
def save_model(self, request, entry, form, change): """Fill the content field with the interpretation of the placeholder""" context = RequestContext(request) entry.content = render_placeholder(entry.content_placeholder, context) super(EntryPlaceholderAdmin, self).save_model( request, entry, form, change)
def save_model(self, request, entry, form, change): """Fill the content field with the interpretation of the placeholder""" context = RequestContext(request) entry.content = render_placeholder(entry.content_placeholder, context) super(EntryPlaceholderAdmin, self).save_model(request, entry, form, change)
def save_model(self, request, gbobject, form, change): """Fill the content field with the interpretation of the placeholder""" context = RequestContext(request) gbobject.content = render_placeholder(gbobject.content_placeholder, context) super(GbobjectPlaceholderAdmin, self).save_model( request, gbobject, form, change)
def render(self, context, width, lang=None): from cms.plugin_rendering import render_placeholder if not 'request' in context: return '<!-- missing request -->' width = width or self.default_width if width: context.update({'width': width}) return render_placeholder(self, context, lang=lang)
def render(self, context, instance, placeholder): html_content = render_placeholder(instance.stack.content, context) context.update({ 'instance': instance, 'placeholder': placeholder, 'content': html_content, }) return context
def save_model(self, request, gbobject, form, change): """Fill the content field with the interpretation of the placeholder""" context = RequestContext(request) gbobject.content = render_placeholder(gbobject.content_placeholder, context) super(GbobjectPlaceholderAdmin, self).save_model(request, gbobject, form, change)
def save_model(self, request, nodetype, form, change): """Fill the content field with the interpretation of the placeholder""" context = RequestContext(request) nodetype.content = render_placeholder(nodetype.content_placeholder, context) super(NodetypePlaceholderAdmin, self).save_model(request, nodetype, form, change)
def render(self, context, width, height=None): from cms.plugin_rendering import render_placeholder if not 'request' in context: return '<!-- missing request -->' context.update({ 'width': width or self.default_width, 'height': height }) return render_placeholder(self, context)
def get_placeholder_content(context, request, current_page, name, inherit): pages = [current_page] if inherit: pages = chain([current_page], current_page.get_cached_ancestors(ascending=True)) for page in pages: placeholder = _get_placeholder(current_page, page, context, name) if placeholder is None: continue if not get_plugins(request, placeholder): continue if hasattr(request, 'placeholder_media'): request.placeholder_media = reduce(operator.add, [request.placeholder_media, placeholder.get_media(request, context)]) #request.placeholder_media += placeholder.get_media(request, context) content = render_placeholder(placeholder, context, name) if content: return content placeholder = _get_placeholder(current_page, current_page, context, name) return render_placeholder(placeholder, context, name)
def test_plugins_children_prepopulate(self): """ Validate a default textplugin with a nested default link plugin """ class NoPushPopContext(Context): def push(self): pass pop = push conf = { "col_left": { "default_plugins": [ { "plugin_type": "TextPlugin", "values": {"body": "<p>body %(_tag_child_1)s and %(_tag_child_2)s</p>"}, "children": [ { "plugin_type": "LinkPlugin", "values": {"name": "django", "url": "https://www.djangoproject.com/"}, }, { "plugin_type": "LinkPlugin", "values": {"name": "django-cms", "url": "https://www.django-cms.org"}, }, ], } ] } } with SettingsOverride(CMS_PLACEHOLDER_CONF=conf): page = create_page("page_en", "col_two.html", "en") placeholder = page.placeholders.get(slot="col_left") context = NoPushPopContext() context["request"] = self.get_request(language="en", page=page) render_placeholder(placeholder, context) plugins = placeholder.get_plugins_list() self.assertEqual(len(plugins), 3) self.assertEqual(plugins[0].plugin_type, "TextPlugin") self.assertEqual(plugins[1].plugin_type, "LinkPlugin") self.assertEqual(plugins[2].plugin_type, "LinkPlugin") self.assertTrue(plugins[1].parent == plugins[2].parent and plugins[1].parent == plugins[0])
def test_plugins_non_default_language_fallback(self): """ Tests language_fallback placeholder configuration """ page_en = create_page("page_en", "col_two.html", "en") create_title("de", "page_de", page_en) placeholder_en = page_en.placeholders.get(slot="col_left") placeholder_de = page_en.placeholders.get(slot="col_left") add_plugin(placeholder_de, TextPlugin, "de", body="de body") class NoPushPopContext(Context): def push(self): pass pop = push context_en = NoPushPopContext() context_en["request"] = self.get_request(language="en", page=page_en) context_de = NoPushPopContext() context_de["request"] = self.get_request(language="de", page=page_en) # First test the default (non-fallback) behavior) ## Deutsch page should have the text plugin content_de = render_placeholder(placeholder_en, context_de) self.assertRegexpMatches(content_de, "^de body$") del (placeholder_en._plugins_cache) cache.clear() ## English page should have no text content_en = render_placeholder(placeholder_en, context_en) self.assertNotRegex(content_en, "^de body$") self.assertEqual(len(content_en), 0) del (placeholder_en._plugins_cache) cache.clear() conf = {"col_left": {"language_fallback": True}} with SettingsOverride(CMS_PLACEHOLDER_CONF=conf): ## English page should have deutsch text content_en = render_placeholder(placeholder_en, context_en) self.assertRegexpMatches(content_en, "^de body$") # remove the cached plugins instances del (placeholder_en._plugins_cache) cache.clear() # Then we add a plugin to check for proper rendering add_plugin(placeholder_en, TextPlugin, "en", body="en body") content_en = render_placeholder(placeholder_en, context_en) self.assertRegexpMatches(content_en, "^en body$")
def placeholder_truncate_words(context, placeholderfield, words=20): from cms.plugin_rendering import render_placeholder if not 'request' in context: return '<!-- missing request -->' html = render_placeholder(placeholderfield, context) return Truncator(html).words(words, html=True, truncate='...')
def test_placeholder_context_leaking(self): TEST_CONF = {"test": {"extra_context": {"width": 10}}} ph = Placeholder.objects.create(slot="test") class NoPushPopContext(Context): def push(self): pass pop = push context = NoPushPopContext() context["request"] = self.get_request() with SettingsOverride(CMS_PLACEHOLDER_CONF=TEST_CONF): render_placeholder(ph, context) self.assertTrue("width" in context) self.assertEqual(context["width"], 10) ph.render(context, None) self.assertTrue("width" in context) self.assertEqual(context["width"], 10)
def render(self, context, width, lang=None, editable=True): ''' Set editable = False to disable front-end rendering for this render. ''' from cms.plugin_rendering import render_placeholder if not 'request' in context: return '<!-- missing request -->' width = width or self.default_width if width: context.update({'width': width}) return render_placeholder(self, context, lang=lang, editable=editable)
def get_content(self, request, current_page, context): pages = [current_page] if self.inherit: pages = chain([current_page], current_page.get_cached_ancestors(ascending=True)) for page in pages: template = get_template_from_request(request, page) placeholder = self._get_placeholder(current_page, page, context, self.name) if placeholder is None: continue if not get_plugins(request, placeholder): continue if hasattr(request, 'placeholder_media'): request.placeholder_media = reduce(operator.add, [request.placeholder_media, placeholder.get_media(request, context)]) #request.placeholder_media += placeholder.get_media(request, context) content = render_placeholder(placeholder, context) if content: return content, placeholder placeholder = self._get_placeholder(current_page, current_page, context, self.name) content = render_placeholder(placeholder, context) return content, placeholder
def render(self, context, width, lang=None, editable=True, use_cache=True): """ Set editable = False to disable front-end rendering for this render. """ from cms.plugin_rendering import render_placeholder if not "request" in context: return "<!-- missing request -->" width = width or self.default_width if width: context.update({"width": width}) return render_placeholder(self, context, lang=lang, editable=editable, use_cache=use_cache)
def _show_content_for_page(context, placeholder_name, page_lookup, lang=None, site=None, cache_result=True, content_max_length=None): """ Shows the content of a page as content of placeholder with name 'content' and given lookup arguments in the given language. This is useful if you want to have some more or less static content that is shared among many pages, such as a footer. See _get_page_by_untyped_arg() for detailed information on the allowed types and their interpretation for the page_lookup argument. """ validate_placeholder_name(placeholder_name) request = context.get('request', False) site_id = get_site_id(site) if not request: return {'content': ''} if lang is None: lang = get_language_from_request(request) if cache_result: base_key = _get_cache_key('_show_content_for_page', page_lookup, lang, site_id) cache_key = _clean_key('%s_placeholder:%s' % (base_key, placeholder_name)) cached_value = cache.get(cache_key) if isinstance(cached_value, dict): # new style _restore_sekizai(context, cached_value['sekizai']) return {'content': mark_safe(cached_value['content'])} elif isinstance(cached_value, basestring): # old style return {'content': mark_safe(cached_value)} page = _get_page_by_untyped_arg(page_lookup, request, site_id) if not page: return {'content': ''} try: placeholder = page.placeholders.get(slot=placeholder_name) except PlaceholderModel.DoesNotExist: if settings.DEBUG: raise return {'content': ''} watcher = Watcher(context) content = render_placeholder(placeholder, context, placeholder_name) if content_max_length: content = remove_tags(content)[:content_max_length] changes = watcher.get_changes() if cache_result: cache.set(cache_key, {'content': content, 'sekizai': changes}, get_cms_setting('CACHE_DURATIONS')['content']) if content: return {'content': mark_safe(content)} return {'content': ''}
def test_plugins_language_fallback(self): """ Tests language_fallback placeholder configuration """ page_en = create_page('page_en', 'col_two.html', 'en') title_de = create_title("de", "page_de", page_en) placeholder_en = page_en.placeholders.get(slot='col_left') placeholder_de = title_de.page.placeholders.get(slot='col_left') add_plugin(placeholder_en, TextPlugin, 'en', body='en body') class NoPushPopContext(Context): def push(self): pass pop = push context_en = NoPushPopContext() context_en['request'] = self.get_request(language="en") context_de = NoPushPopContext() context_de['request'] = self.get_request(language="de") # First test the default (non-fallback) behavior) ## English page should have the text plugin content_en = render_placeholder(placeholder_en, context_en) self.assertRegexpMatches(content_en,"^en body$") ## Deutsch page should have no text content_de = render_placeholder(placeholder_en, context_de) self.assertNotRegexpMatches(content_de,"^en body$") conf = { 'col_left': { 'language_fallback': True, }, } with SettingsOverride(CMS_PLACEHOLDER_CONF=conf): ## Deutsch page should have no text content_de = render_placeholder(placeholder_en, context_de) self.assertRegexpMatches(content_de,"^en body$") # Then we add a plugin to check for proper rendering add_plugin(placeholder_de, TextPlugin, 'de', body='de body') content_de = render_placeholder(placeholder_de, context_de) self.assertRegexpMatches(content_de,"^de body$")
def html_content(self): """ Render the content_placeholder field dynamicly. https://github.com/Fantomas42/cmsplugin-zinnia/issues/3 """ context = self.acquire_context() try: return render_placeholder(self.content_placeholder, context) except AttributeError: # Should happen when ``context`` and ``request`` # have not been found in the stack. pass return self.content # Ultimate fallback
def get_placeholder_content(context, request, current_page, name, inherit): edit_mode = getattr(request, 'toolbar', None) and getattr(request.toolbar, 'edit_mode') pages = [current_page] # don't display inherited plugins in edit mode, so that the user doesn't # mistakenly edit/delete them. This is a fix for issue #1303. See the discussion # there for possible enhancements if inherit and not edit_mode: pages = chain([current_page], current_page.get_cached_ancestors(ascending=True)) for page in pages: placeholder = _get_placeholder(current_page, page, context, name) if placeholder is None: continue if not get_plugins(request, placeholder): continue content = render_placeholder(placeholder, context, name) if content: return content # if we reach this point, we have an empty or non-existant placeholder # call _get_placeholder again to get the placeholder properly rendered # in frontend editing placeholder = _get_placeholder(current_page, current_page, context, name) return render_placeholder(placeholder, context, name)
def get_placeholder_content(context, request, current_page, name, inherit): pages = [current_page] if inherit: pages = chain([current_page], current_page.get_cached_ancestors(ascending=True)) for page in pages: placeholder = _get_placeholder(current_page, page, context, name) if placeholder is None: continue if not get_plugins(request, placeholder): continue if hasattr(request, 'placeholder_media'): request.placeholder_media = reduce(operator.add, [ request.placeholder_media, placeholder.get_media(request, context) ]) #request.placeholder_media += placeholder.get_media(request, context) content = render_placeholder(placeholder, context, name) if content: return content placeholder = _get_placeholder(current_page, current_page, context, name) return render_placeholder(placeholder, context, name)
def render(self, context, instance, placeholder): context['instance'] = instance context['placeholder'] = placeholder if instance.plugin_id: plugins = instance.plugin.get_descendants(include_self=True).order_by('placeholder', 'tree_id', 'level', 'position') plugins = downcast_plugins(plugins) plugins[0].parent_id = None plugins = build_plugin_tree(plugins) context['plugins'] = plugins if instance.alias_placeholder_id: content = render_placeholder(instance.alias_placeholder, context) context['content'] = mark_safe(content) return context
def _show_placeholder_for_page(context, placeholder_name, page_lookup, lang=None, site=None, cache_result=True): """ Shows the content of a page with a placeholder name and given lookup arguments in the given language. This is useful if you want to have some more or less static content that is shared among many pages, such as a footer. See _get_page_by_untyped_arg() for detailed information on the allowed types and their interpretation for the page_lookup argument. """ validate_placeholder_name(placeholder_name) request = context.get('request', False) site_id = get_site_id(site) if not request: return {'content': ''} if lang is None: lang = get_language_from_request(request) page = _get_page_by_untyped_arg(page_lookup, request, site_id) if not page: return {'content': ''} try: placeholder = page.placeholders.get(slot=placeholder_name) except PlaceholderModel.DoesNotExist: if settings.DEBUG: raise return {'content': ''} if cache_result: cached_value = get_placeholder_cache(placeholder, lang, site_id, request) if cached_value: restore_sekizai_context(context, cached_value['sekizai']) return {'content': mark_safe(cached_value['content'])} watcher = Watcher(context) content = render_placeholder(placeholder, context, placeholder_name, lang=lang, use_cache=cache_result) changes = watcher.get_changes() edit_mode = hasattr(request, 'toolbar') and getattr(request.toolbar, 'edit_mode', False) if not edit_mode and placeholder and placeholder.cache_placeholder and get_cms_setting('PLACEHOLDER_CACHE') and cache_result: # noqa set_placeholder_cache(placeholder, lang, site_id, {'content': content, 'sekizai': changes}, request) if content: return {'content': mark_safe(content)} return {'content': ''}
def render(self, context, instance, placeholder): from cms.utils.plugins import downcast_plugins, build_plugin_tree context['instance'] = instance context['placeholder'] = placeholder if instance.plugin_id: plugins = instance.plugin.get_descendants().order_by( 'placeholder', 'path') plugins = [instance.plugin] + list(plugins) plugins = downcast_plugins(plugins) plugins[0].parent_id = None plugins = build_plugin_tree(plugins) context['plugins'] = plugins if instance.alias_placeholder_id: content = render_placeholder(instance.alias_placeholder, context) context['content'] = mark_safe(content) return context
def _show_placeholder_for_page(context, placeholder_name, page_lookup, lang=None, site=None, cache_result=True): """ Shows the content of a page with a placeholder name and given lookup arguments in the given language. This is useful if you want to have some more or less static content that is shared among many pages, such as a footer. See _get_page_by_untyped_arg() for detailed information on the allowed types and their interpretation for the page_lookup argument. """ validate_placeholder_name(placeholder_name) request = context.get('request', False) site_id = get_site_id(site) if not request: return {'content': ''} if lang is None: lang = get_language_from_request(request) content = None if cache_result: base_key = _get_cache_key('_show_placeholder_for_page', page_lookup, lang, site_id) cache_key = _clean_key('%s_placeholder:%s' % (base_key, placeholder_name)) content = cache.get(cache_key) if not content: page = _get_page_by_untyped_arg(page_lookup, request, site_id) if not page: return {'content': ''} try: placeholder = page.placeholders.get(slot=placeholder_name) except PlaceholderModel.DoesNotExist: if settings.DEBUG: raise return {'content': ''} content = render_placeholder(placeholder, context, placeholder_name) if cache_result: cache.set(cache_key, content, settings.CMS_CACHE_DURATIONS['content']) if content: return {'content': mark_safe(content)} return {'content': ''}
def _render(self, instance): context = SekizaiContext() context['request'] = self.request try: # django CMS 3.4+ from cms.plugin_rendering import ContentRenderer renderer = ContentRenderer(self.request) context['cms_content_renderer'] = renderer rendered = renderer.render_placeholder(instance, context, language=self.language, editable=False) except ImportError: # django CMS 3.3 and below from cms.plugin_rendering import render_placeholder rendered = render_placeholder(instance, context, lang=self.language, editable=False) flat = flatten_context(context) return rendered.strip(), flat
def render_tag(self, context, code, varname): # TODO: language override (the reason this is not implemented, is that language selection is buried way # down somewhere in some method called in render_plugins. There it gets extracted from the request # and a language in request.GET always overrides everything.) if not code: # an empty string was passed in or the variable is not available in the context return '' # TODO: caching? request = context.get('request', False) if not request: return '' if isinstance(code, Stack): stack = code else: stack, __ = Stack.objects.get_or_create( code=code, defaults={ 'name': code, 'creation_method': Stack.CREATION_BY_TEMPLATE }) placeholder = stack.content return render_placeholder(placeholder, context, name_fallback=code)
def get_value(self, context, **kwargs): placeholder = kwargs.get('placeholder') if not placeholder: return '' width = kwargs.get('width') lang = kwargs.get('language') context.push() request = HttpRequest() request.user = AnonymousUser() request.current_page = None context['request'] = request obj = context.get('object') content = render_placeholder( obj.placeholder, context, name_fallback=placeholder, lang=lang, default=None, editable=True, use_cache=True) #, editable=False, use_cache=False) return strip_tags(content)
def test_children_hidden(self): page1, = self.get_pages() ph = page1.placeholders.get(slot='content') date_start = now() text_content = u"Child plugin" plugin_data = { 'date_publish': date_start + timedelta(days=1), } plugin_1 = add_plugin(ph, 'TimerContainerPlugin', language='en', **plugin_data) plugin_1.save() # child of plugin_1 plugin_2 = add_plugin(ph, u"TextPlugin", u"en", body=text_content) plugin_1 = self.reload_model(plugin_1) plugin_2.parent = plugin_1 plugin_2.save() request = self.get_page_request(page1, self.user, r'/en/', lang='en') context = RequestContext(request, {}) content = render_placeholder(ph, context) self.assertEqual(content, '')