def get_languages(site_id=None): site_id = get_site_id(site_id) result = get_cms_setting('LANGUAGES').get(site_id) if not result: result = [] defaults = get_cms_setting('LANGUAGES').get('default', {}) for code, name in settings.LANGUAGES: lang = {'code': code, 'name': _(name)} lang.update(defaults) result.append(lang) get_cms_setting('LANGUAGES')[site_id] = result return result
def render_placeholder(self, placeholder, context, language=None, page=None, editable=False, use_cache=False, nodelist=None, width=None): from sekizai.helpers import Watcher from cms.utils.plugins import get_plugins language = language or self.request_language editable = editable and self._placeholders_are_editable if use_cache and not editable and placeholder.cache_placeholder: use_cache = self.placeholder_cache_is_enabled() else: use_cache = False if page: site_id = page.site_id template = page.get_template() else: site_id = get_site_id(None) template = None if use_cache: cached_value = self._get_cached_placeholder_content( placeholder=placeholder, site_id=site_id, language=language, ) else: cached_value = None if cached_value is not None: # User has opted to use the cache # and there is something in the cache restore_sekizai_context(context, cached_value['sekizai']) return mark_safe(cached_value['content']) context.push() width = width or placeholder.default_width if width: context['width'] = width # 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? for key, value in placeholder.get_extra_context(template).items(): if key not in context: context[key] = value if use_cache: watcher = Watcher(context) plugins = get_plugins( request=self.request, placeholder=placeholder, template=template, lang=language, ) if plugins: plugin_content = self.render_plugins( plugins=plugins, context=context, placeholder=placeholder, editable=editable, ) placeholder_content = ''.join(plugin_content) elif nodelist: # should be nodelist from a template placeholder_content = nodelist.render(context) else: placeholder_content = '' if use_cache: content = { 'content': placeholder_content, 'sekizai': watcher.get_changes(), } set_placeholder_cache( placeholder, lang=language, site_id=site_id, content=content, request=self.request, ) if editable: toolbar_content = self.render_editable_placeholder( placeholder=placeholder, context=context, language=language, ) else: toolbar_content = '' rendered_placeholder = RenderedPlaceholder( placeholder=placeholder, language=language, site_id=site_id, cached=use_cache, editable=editable, has_content=bool(placeholder_content), ) if placeholder.pk not in self._rendered_placeholders: # First time this placeholder is rendered if not self.toolbar._cache_disabled: # The toolbar middleware needs to know if the response # is to be cached. # Set the _cache_disabled flag to the value of cache_placeholder # only if the flag is False (meaning cache is enabled). self.toolbar._cache_disabled = not use_cache self._rendered_placeholders[placeholder.pk] = rendered_placeholder context.pop() return mark_safe(toolbar_content + placeholder_content)
def render_placeholder(placeholder, context_to_copy, name_fallback="Placeholder", lang=None, default=None, editable=True, use_cache=True): """ Renders plugins for a placeholder on the given page using shallow copies of the given context, and returns a string containing the rendered output. Set editable = False to disable front-end editing for this placeholder during rendering. This is primarily used for the "as" variant of the render_placeholder tag. """ from cms.utils.placeholder import get_placeholder_conf, restore_sekizai_context from cms.utils.plugins import get_plugins # these are always called before all other plugin context processors from sekizai.helpers import Watcher if not placeholder: return context = copy(context_to_copy) context.push() request = context['request'] if not hasattr(request, 'placeholders'): request.placeholders = {} # Prepend frontedit toolbar output if applicable try: toolbar = getattr(request, 'toolbar', None) except AttributeError: toolbar = None if (toolbar and toolbar.edit_mode and toolbar.show_toolbar and placeholder.is_editable and editable): from cms.middleware.toolbar import toolbar_plugin_processor processors = (toolbar_plugin_processor,) edit = True else: processors = None edit = False if edit: perms = (placeholder.has_change_permission(request) or not placeholder.cache_placeholder) if not perms or placeholder.slot not in request.placeholders: request.placeholders[placeholder.slot] = (placeholder, perms) else: request.placeholders[placeholder.slot] = ( placeholder, perms and request.placeholders[placeholder.slot][1] ) else: request.placeholders[placeholder.slot] = ( placeholder, False ) if hasattr(placeholder, 'content_cache'): return mark_safe(placeholder.content_cache) page = placeholder.page if placeholder else None if page: site_id = page.site_id else: site_id = get_site_id(None) # It's kind of duplicate of the similar call in `get_plugins`, but it's required # to have a valid language in this function for `get_fallback_languages` to work if lang: save_language = lang else: lang = get_language_from_request(request) save_language = lang use_cache = use_cache and not request.user.is_authenticated() if get_cms_setting('PLACEHOLDER_CACHE') and use_cache: if not edit and placeholder and not hasattr(placeholder, 'cache_checked'): cached_value = get_placeholder_cache(placeholder, lang, site_id, request) if cached_value is not None: restore_sekizai_context(context, cached_value['sekizai']) return mark_safe(cached_value['content']) if page: template = page.template else: template = None plugins = [plugin for plugin in get_plugins(request, placeholder, template, lang=lang)] # 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) if slot: for key, value in get_placeholder_conf("extra_context", slot, template, {}).items(): if key not in context: context[key] = value content = [] watcher = Watcher(context) content.extend(render_plugins(plugins, context, placeholder, processors)) toolbar_content = '' if edit and editable: if not hasattr(request.toolbar, 'placeholder_list'): request.toolbar.placeholder_list = [] if placeholder not in request.toolbar.placeholder_list: request.toolbar.placeholder_list.append(placeholder) toolbar_content = mark_safe(render_placeholder_toolbar(placeholder, context, name_fallback, save_language)) if content: content = mark_safe("".join(content)) elif default: # should be nodelist from a template content = mark_safe(default.render(context_to_copy)) else: content = '' context['content'] = content context['placeholder'] = toolbar_content context['edit'] = edit result = render_to_string("cms/toolbar/content.html", flatten_context(context)) changes = watcher.get_changes() if use_cache and placeholder.cache_placeholder and get_cms_setting('PLACEHOLDER_CACHE'): content = {'content': result, 'sekizai': changes} set_placeholder_cache(placeholder, lang, site_id, content=content, request=request) context.pop() return result
def render_placeholder(placeholder, context_to_copy, name_fallback="Placeholder", lang=None, default=None, editable=True, use_cache=True): """ Renders plugins for a placeholder on the given page using shallow copies of the given context, and returns a string containing the rendered output. Set editable = False to disable front-end editing for this placeholder during rendering. This is primarily used for the "as" variant of the render_placeholder tag. """ from cms.utils.placeholder import get_placeholder_conf, restore_sekizai_context from cms.utils.plugins import get_plugins # these are always called before all other plugin context processors from sekizai.helpers import Watcher if not placeholder: return context = copy(context_to_copy) context.push() request = context['request'] if not hasattr(request, 'placeholders'): request.placeholders = {} # Prepend frontedit toolbar output if applicable try: toolbar = getattr(request, 'toolbar', None) except AttributeError: toolbar = None if (toolbar and toolbar.edit_mode and toolbar.show_toolbar and placeholder.is_editable and editable): from cms.middleware.toolbar import toolbar_plugin_processor processors = (toolbar_plugin_processor, ) edit = True else: processors = None edit = False if edit: perms = (placeholder.has_change_permission(request) or not placeholder.cache_placeholder) if not perms or placeholder.slot not in request.placeholders: request.placeholders[placeholder.slot] = (placeholder, perms) else: request.placeholders[placeholder.slot] = ( placeholder, perms and request.placeholders[placeholder.slot][1]) else: request.placeholders[placeholder.slot] = (placeholder, False) if hasattr(placeholder, 'content_cache'): return mark_safe(placeholder.content_cache) page = placeholder.page if placeholder else None if page: site_id = page.site_id else: site_id = get_site_id(None) # It's kind of duplicate of the similar call in `get_plugins`, but it's required # to have a valid language in this function for `get_fallback_languages` to work if lang: save_language = lang else: lang = get_language_from_request(request) save_language = lang use_cache = use_cache and not request.user.is_authenticated() if get_cms_setting('PLACEHOLDER_CACHE') and use_cache: if not edit and placeholder and not hasattr(placeholder, 'cache_checked'): cached_value = get_placeholder_cache(placeholder, lang, site_id, request) if cached_value is not None: restore_sekizai_context(context, cached_value['sekizai']) return mark_safe(cached_value['content']) if page: template = page.template else: template = None plugins = [ plugin for plugin in get_plugins(request, placeholder, template, lang=lang) ] # 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) if slot: for key, value in get_placeholder_conf("extra_context", slot, template, {}).items(): if key not in context: context[key] = value content = [] watcher = Watcher(context) content.extend(render_plugins(plugins, context, placeholder, processors)) toolbar_content = '' if edit and editable: if not hasattr(request.toolbar, 'placeholder_list'): request.toolbar.placeholder_list = [] if placeholder not in request.toolbar.placeholder_list: request.toolbar.placeholder_list.append(placeholder) toolbar_content = mark_safe( render_placeholder_toolbar(placeholder, context, name_fallback, save_language)) if content: content = mark_safe("".join(content)) elif default: # should be nodelist from a template content = mark_safe(default.render(context_to_copy)) else: content = '' context['content'] = content context['placeholder'] = toolbar_content context['edit'] = edit result = render_to_string("cms/toolbar/content.html", flatten_context(context)) changes = watcher.get_changes() if use_cache and placeholder.cache_placeholder and get_cms_setting( 'PLACEHOLDER_CACHE'): content = {'content': result, 'sekizai': changes} set_placeholder_cache(placeholder, lang, site_id, content=content, request=request) context.pop() return result