def get_page_tags_from_request(request, page_lookup, lang, site, title=False): """ Get the list of tags attached to a Page or a Title from a request from usual `page_lookup` parameters. :param request: request object :param page_lookup: a valid page_lookup argument :param lang: a language code :param site: a site id :param title: a boolean to extract the Page (if False) or Title instance :return: list of tags :type: List """ from cms.templatetags.cms_tags import _get_page_by_untyped_arg from cms.utils import get_language_from_request, get_cms_setting, get_site_id from django.core.cache import cache site_id = get_site_id(site) if lang is None: lang = get_language_from_request(request) cache_key = get_cache_key(request, page_lookup, lang, site, title) tags_list = cache.get(cache_key) if not tags_list: page = _get_page_by_untyped_arg(page_lookup, request, site_id) if page: if title: tags_list = get_title_tags(page, lang) else: tags_list = get_page_tags(page) cache.set(cache_key, tags_list, timeout=get_cms_setting('CACHE_DURATIONS')['content']) if not tags_list: tags_list = () return tags_list
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'): site_id = get_site_id(getattr(page, 'site_id', None)) cached_value = get_placeholder_cache(placeholder, get_language(), site_id, request) 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 get_value(self, context, page_lookup, lang, site): from django.core.cache import cache site_id = get_site_id(site) request = context.get('request', False) if not request: return '' if lang is None: lang = get_language_from_request(request) cache_key = _get_cache_key('page_url', page_lookup, lang, site_id) + \ '_type:absolute_url' url = cache.get(cache_key) if not url: page = _get_page_by_untyped_arg(page_lookup, request, site_id) if page: url = page.get_absolute_url(language=lang) cache.set(cache_key, url, get_cms_setting('CACHE_DURATIONS')['content']) if url: return url return ''
def mark_as_dirty(self, language, clear_cache=True): """ Utility method to mark the attached object of this placeholder (if any) as dirty. This allows us to know when the content in this placeholder has been changed. """ from cms.models import Page, StaticPlaceholder, Title if clear_cache: clear_placeholder_cache( self, language, get_site_id(getattr(self.page, 'site_id', None))) # Find the attached model for this placeholder # This can be a static placeholder, page or none. attached_model = self._get_attached_model() if attached_model is Page: Title.objects.filter( page=self.page, language=language, ).update(publisher_state=PUBLISHER_STATE_DIRTY) elif attached_model is StaticPlaceholder: StaticPlaceholder.objects.filter(draft=self).update(dirty=True)
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. """ from django.core.cache import cache 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 cached_value: restore_sekizai_context(context, cached_value['sekizai']) return {'content': mark_safe(cached_value['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': ''} watcher = Watcher(context) content = render_placeholder(placeholder, context, placeholder_name, use_cache=cache_result) 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 _show_placeholder_by_id(context, placeholder_name, reverse_id, lang=None, site=None, use_cache=True): validate_placeholder_name(placeholder_name) content_renderer = context.get('cms_content_renderer') site_id = get_site_id(site) if not content_renderer: return '' page = _get_page_by_untyped_arg(reverse_id, content_renderer.request, site_id) if not page: return '' try: placeholder = page.placeholders.get(slot=placeholder_name) except PlaceholderModel.DoesNotExist: if settings.DEBUG: raise return '' content_renderer = context['cms_content_renderer'] content = content_renderer.render_placeholder( placeholder=placeholder, context=context, language=lang, page=page, editable=False, use_cache=use_cache, ) return content
def get_value(self, context, name, article_lookup): if 'request' not in context: return '' name = name.lower() request = context['request'] lang = get_language_from_request(request) article = _get_article_by_untyped_arg(article_lookup, request, get_site_id(None)) if article and name in self.valid_attributes: func = getattr(article, "get_%s" % name) ret_val = func(language=lang, fallback=True) if name not in ("changed_date", "image"): ret_val = escape(ret_val) return ret_val return ''
def get_value(self, context, name, page_lookup): if not 'request' in context: return '' name = name.lower() request = context['request'] lang = get_language_from_request(request) page = _get_page_by_untyped_arg(page_lookup, request, get_site_id(None)) if page and name in self.valid_attributes: func = getattr(page, "get_%s" % name) ret_val = func(language=lang, fallback=True) if not isinstance(ret_val, datetime): ret_val = escape(ret_val) return ret_val return ''
def render_tag(self, context, name, page_lookup, extra_bits, nodelist=None): validate_placeholder_name(name) request = context.get("request") if request: page = _get_page_by_untyped_arg(page_lookup, request, get_site_id(None)) toolbar = get_toolbar_from_request(request) renderer = toolbar.get_content_renderer() inherit = "inherit" in extra_bits # A placeholder is only editable on its own page editable = page == request.current_page try: content = renderer.render_page_placeholder( slot=name, context=context, inherit=inherit, page=page, nodelist=nodelist, editable=editable, ) except PlaceholderNotFound: content = "" else: content = "" if not content and nodelist: content = nodelist.render(context) if "as" in extra_bits: try: varname = extra_bits[extra_bits.index("as") + 1] except IndexError: raise template.TemplateSyntaxError( 'the "as" word should be followed by the variable name') context[varname] = content return "" return content
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) if DJANGO_1_7: request = context.get('request', False) else: request = context.request site_id = get_site_id(site) if not request: return {'content': ''} if lang is None: lang = get_language_from_request(request) if cache_result: cached_value = get_placeholder_page_cache(page_lookup, lang, site_id, placeholder_name) if cached_value: restore_sekizai_context(context, cached_value['sekizai']) return {'content': mark_safe(cached_value['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': ''} watcher = Watcher(context) content = render_placeholder(placeholder, context, placeholder_name, use_cache=cache_result) changes = watcher.get_changes() if cache_result: set_placeholder_page_cache(page_lookup, lang, site_id, placeholder_name, {'content': content, 'sekizai': changes}) if content: return {'content': mark_safe(content)} return {'content': ''}
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_tag(self, context, name, page_lookup, varname, extra_bits, nodelist=None): """ Retrieves the placeholder's plugins and set them as a variable in the template context. If the placeholder is empty, render the block as fallback content and return the resulting HTML. If the placholder is editable, the edit script and markup are added to the HTML content. """ content = "" request = context.get("request") if request: page = _get_page_by_untyped_arg(page_lookup, request, get_site_id(None)) try: placeholder = page.placeholders.get(slot=name) except ObjectDoesNotExist: context[varname] = [] return "" else: context[varname] = [ cms_plugin.get_plugin_instance()[0] for cms_plugin in get_plugins( request, placeholder, template=page.get_template()) ] # Default content if there is no plugins in the placeholder if not context[varname] and nodelist: content = nodelist.render(context) # Add the edit script and markup to the content, only if the placeholder is editable # and the visited page is the one on which the placeholder is declared. toolbar = get_toolbar_from_request(request) if placeholder.page == request.current_page and toolbar.edit_mode_active: renderer = toolbar.get_content_renderer() data = renderer.get_editable_placeholder_context(placeholder, page=page) data["content"] = content content = renderer.placeholder_edit_template.format(**data) return content
def get_value(self, context, page_lookup, lang, site): site_id = get_site_id(site) request = context.get('request', False) if not request: return '' if lang is None: lang = get_language_from_request(request) url = get_page_url_cache(page_lookup, lang, site_id) if url is None: page = _get_page_by_untyped_arg(page_lookup, request, site_id) if page: url = page.get_absolute_url(language=lang) set_page_url_cache(page_lookup, lang, site_id, url) if url: return url return ''
def mark_as_dirty(self, language, clear_cache=True): """ Utility method to mark the attached object of this placeholder (if any) as dirty. This allows us to know when the content in this placeholder has been changed. """ from cms.models import Page, StaticPlaceholder, Title if clear_cache: clear_placeholder_cache(self, language, get_site_id(getattr(self.page, 'site_id', None))) # Find the attached model for this placeholder # This can be a static placeholder, page or none. attached_model = self._get_attached_model() if attached_model is Page: Title.objects.filter( page=self.page, language=language, ).update(publisher_state=PUBLISHER_STATE_DIRTY) elif attached_model is StaticPlaceholder: StaticPlaceholder.objects.filter(draft=self).update(dirty=True)
def clear_cache(self, language, site_id=None): if not site_id: site_id = getattr(self.page, 'site_id', None) clear_placeholder_cache(self, language, get_site_id(site_id))
def test_get_site_id_from_str(self): with self.settings(SITE_ID=10): self.assertEqual(10, get_site_id("something"))
def test_get_site_id_from_str_int(self): self.assertEqual(10, get_site_id('10'))
def test_get_site_id_from_site(self): site = Site() site.id = 10 self.assertEqual(10, get_site_id(site))
def test_get_site_id_from_int(self): self.assertEqual(10, get_site_id(10))
def test_get_site_id_from_nothing(self): with self.settings(SITE_ID=10): self.assertEqual(10, get_site_id(None))
def test_get_site_id_from_str(self): with SettingsOverride(SITE_ID=10): self.assertEqual(10, get_site_id("something"))
def test_get_site_id_from_nothing(self): with SettingsOverride(SITE_ID=10): self.assertEqual(10, get_site_id(None))
def clear_cache(self, language, site_id=None): if not site_id and self.page: site_id = self.page.node.site_id clear_placeholder_cache(self, language, get_site_id(site_id))