def _get_placeholder(current_page, page, context, name): placeholder_cache = getattr(current_page, '_tmp_placeholders_cache', {}) if page.pk in placeholder_cache: placeholder = placeholder_cache[page.pk].get(name, None) if placeholder: return placeholder placeholder_cache[page.pk] = {} placeholders = page.rescan_placeholders().values() fetch_placeholders = [] request = context['request'] if not get_cms_setting('PLACEHOLDER_CACHE') or (hasattr(request, 'toolbar') and request.toolbar.edit_mode): fetch_placeholders = placeholders else: for placeholder in placeholders: cached_value = get_placeholder_cache(placeholder, get_language()) if cached_value is not None: restore_sekizai_context(context, cached_value['sekizai']) placeholder.content_cache = cached_value['content'] else: fetch_placeholders.append(placeholder) placeholder.cache_checked = True if fetch_placeholders: assign_plugins(context['request'], fetch_placeholders, page.get_template(), get_language()) for placeholder in placeholders: placeholder_cache[page.pk][placeholder.slot] = placeholder placeholder.page = page current_page._tmp_placeholders_cache = placeholder_cache placeholder = placeholder_cache[page.pk].get(name, None) if page.application_urls and not placeholder: raise PlaceholderNotFound( '"%s" placeholder not found in an apphook application. Please use a static placeholder instead.' % name) return placeholder
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') context_en = SekizaiContext() context_en['request'] = self.get_request(language="en", page=page_en) conf = { 'col_left': { 'language_fallback': True, }, } with self.settings(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 _get_placeholder(current_page, page, context, name): from django.core.cache import cache placeholder_cache = getattr(current_page, '_tmp_placeholders_cache', {}) if page.pk in placeholder_cache: placeholder = placeholder_cache[page.pk].get(name, None) if placeholder: return placeholder placeholder_cache[page.pk] = {} placeholders = page.rescan_placeholders().values() fetch_placeholders = [] request = context['request'] if not get_cms_setting('PLACEHOLDER_CACHE') or (hasattr(request, 'toolbar') and request.toolbar.edit_mode): fetch_placeholders = placeholders else: for placeholder in placeholders: 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']) placeholder.content_cache = cached_value['content'] else: fetch_placeholders.append(placeholder) placeholder.cache_checked = True if fetch_placeholders: assign_plugins(context['request'], fetch_placeholders, page.get_template(), get_language()) for placeholder in placeholders: placeholder_cache[page.pk][placeholder.slot] = placeholder placeholder.page = page current_page._tmp_placeholders_cache = placeholder_cache placeholder = placeholder_cache[page.pk].get(name, None) if page.application_urls and not placeholder: raise PlaceholderNotFound( '"%s" placeholder not found in an apphook application. Please use a static placeholder instead.' % name) return placeholder
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') context_en = SekizaiContext() context_en['request'] = self.get_request(language="en", page=page_en) conf = { 'col_left': { 'language_fallback': True, }, } with self.settings(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 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 _preload_placeholders_for_page(self, page): """ Populates the internal plugin cache of each placeholder in the given page if the placeholder has not been previously cached. """ from cms.utils.plugins import assign_plugins site_id = page.site_id placeholders = page.rescan_placeholders().values() if self.placeholder_cache_is_enabled(): _cached_content = self._get_cached_placeholder_content # Only prefetch placeholder plugins if the placeholder # has not been cached. placeholders_to_fetch = [ placeholder for placeholder in placeholders if _cached_content( placeholder, site_id, self.request_language) == None ] else: # cache is disabled, prefetch plugins for all # placeholders in the page. placeholders_to_fetch = placeholders if placeholders_to_fetch: assign_plugins( request=self.request, placeholders=placeholders_to_fetch, template=page.get_template(), lang=self.request_language, ) # Internal cache mapping placeholder slots # to placeholder instances. page_placeholder_cache = {} for placeholder in placeholders: # Save a query when the placeholder toolbar is rendered. placeholder.page = page page_placeholder_cache[placeholder.slot] = placeholder self._placeholders_by_page_cache[page.pk] = page_placeholder_cache
def _preload_placeholders_for_page(self, page): """ Populates the internal plugin cache of each placeholder in the given page if the placeholder has not been previously cached. """ from cms.utils.plugins import assign_plugins site_id = page.site_id placeholders = page.rescan_placeholders().values() if self.placeholder_cache_is_enabled(): _cached_content = self._get_cached_placeholder_content # Only prefetch placeholder plugins if the placeholder # has not been cached. placeholders_to_fetch = [ placeholder for placeholder in placeholders if _cached_content(placeholder, site_id, self.request_language) == None] else: # cache is disabled, prefetch plugins for all # placeholders in the page. placeholders_to_fetch = placeholders if placeholders_to_fetch: assign_plugins( request=self.request, placeholders=placeholders_to_fetch, template=page.get_template(), lang=self.request_language, ) # Internal cache mapping placeholder slots # to placeholder instances. page_placeholder_cache = {} for placeholder in placeholders: # Save a query when the placeholder toolbar is rendered. placeholder.page = page page_placeholder_cache[placeholder.slot] = placeholder self._placeholders_by_page_cache[page.pk] = page_placeholder_cache
def _preload_placeholders_for_page(self, page, slots=None, inherit=False): """ Populates the internal plugin cache of each placeholder in the given page if the placeholder has not been previously cached. """ from cms.utils.plugins import assign_plugins site_id = page.site_id if slots: placeholders = page.get_placeholders().filter(slot__in=slots) else: # Creates any placeholders missing on the page placeholders = page.rescan_placeholders().values() if inherit: # When the inherit flag is True, # assume all placeholders found are inherited and thus prefetch them. slots_w_inheritance = [pl.slot for pl in placeholders] elif not self.toolbar.edit_mode: # Scan through the page template to find all placeholders # that have inheritance turned on. slots_w_inheritance = [pl.slot for pl in page.get_declared_placeholders() if pl.inherit] else: # Inheritance is turned off on edit-mode slots_w_inheritance = [] if self.placeholder_cache_is_enabled(): _cached_content = self._get_cached_placeholder_content # Only prefetch plugins if the placeholder # has not been cached. placeholders_to_fetch = [ placeholder for placeholder in placeholders if _cached_content(placeholder, site_id, self.request_language) == None] else: # cache is disabled, prefetch plugins for all # placeholders in the page. placeholders_to_fetch = placeholders if placeholders_to_fetch: assign_plugins( request=self.request, placeholders=placeholders_to_fetch, template=page.get_template(), lang=self.request_language, is_fallback=inherit, ) # Inherit only placeholders that have no plugins # or are not cached. placeholders_to_inherit = [ pl.slot for pl in placeholders if not getattr(pl, '_plugins_cache', None) and pl.slot in slots_w_inheritance ] if placeholders_to_inherit and page.parent_id: self._preload_placeholders_for_page( page=page.parent, slots=placeholders_to_inherit, inherit=True, ) # Internal cache mapping placeholder slots # to placeholder instances. page_placeholder_cache = {} for placeholder in placeholders: # Save a query when the placeholder toolbar is rendered. placeholder.page = page page_placeholder_cache[placeholder.slot] = placeholder self._placeholders_by_page_cache[page.pk] = page_placeholder_cache
def _preload_placeholders_for_page(self, page, slots=None, inherit=False): """ Populates the internal plugin cache of each placeholder in the given page if the placeholder has not been previously cached. """ from cms.utils.plugins import assign_plugins site_id = page.site_id if slots: placeholders = page.get_placeholders().filter(slot__in=slots) else: # Creates any placeholders missing on the page placeholders = page.rescan_placeholders().values() if inherit: # When the inherit flag is True, # assume all placeholders found are inherited and thus prefetch them. slots_w_inheritance = [pl.slot for pl in placeholders] elif not self.toolbar.edit_mode: # Scan through the page template to find all placeholders # that have inheritance turned on. slots_w_inheritance = [ pl.slot for pl in page.get_declared_placeholders() if pl.inherit ] else: # Inheritance is turned off on edit-mode slots_w_inheritance = [] if self.placeholder_cache_is_enabled(): _cached_content = self._get_cached_placeholder_content # Only prefetch plugins if the placeholder # has not been cached. placeholders_to_fetch = [ placeholder for placeholder in placeholders if _cached_content( placeholder, site_id, self.request_language) == None ] else: # cache is disabled, prefetch plugins for all # placeholders in the page. placeholders_to_fetch = placeholders if placeholders_to_fetch: assign_plugins( request=self.request, placeholders=placeholders_to_fetch, template=page.get_template(), lang=self.request_language, is_fallback=inherit, ) # Inherit only placeholders that have no plugins # or are not cached. placeholders_to_inherit = [ pl.slot for pl in placeholders if not getattr(pl, '_plugins_cache', None) and pl.slot in slots_w_inheritance ] if placeholders_to_inherit and page.parent_id: self._preload_placeholders_for_page( page=page.parent, slots=placeholders_to_inherit, inherit=True, ) # Internal cache mapping placeholder slots # to placeholder instances. page_placeholder_cache = {} for placeholder in placeholders: # Save a query when the placeholder toolbar is rendered. placeholder.page = page page_placeholder_cache[placeholder.slot] = placeholder self._placeholders_by_page_cache[page.pk] = page_placeholder_cache