Beispiel #1
0
    def _get_title_cache(self, language, fallback, force_reload):
        if not language:
            language = get_language()
        load = False
        if not hasattr(self, 'title_cache') or force_reload:
            load = True
            self.title_cache = {}
        elif language not in self.title_cache:
            if fallback:
                fallback_langs = i18n.get_fallback_languages(language)
                for lang in fallback_langs:
                    if lang in self.title_cache:
                        return lang
            load = True
        if load:
            from .title import Title

            titles = Title.objects.filter(article=self)
            for title in titles:
                self.title_cache[title.language] = title
            if language in self.title_cache:
                return language
            else:
                if fallback:
                    fallback_langs = i18n.get_fallback_languages(language)
                    for lang in fallback_langs:
                        if lang in self.title_cache:
                            return lang
        return language
Beispiel #2
0
def get_current_page(path, lang, queryset, home_slug, home_tree_id):
    """Helper for getting current page from path depending on language
    
    returns: (Page, None) or (None, path_to_alternative language)
    """
    try:
        if home_slug:
            queryset = queryset.exclude(Q(title_set__path=home_slug)&Q(tree_id=home_tree_id))
            home_slug += "/"
            title_q = Q(title_set__path=path)|(Q(title_set__path=home_slug + path)&Q(tree_id=home_tree_id))
            
        else:
            title_q = Q(title_set__slug=path)
        if settings.CMS_FLAT_URLS:
            return queryset.filter(title_q & Q(title_set__language=lang)).distinct().select_related()[0], None
        else:
            page = queryset.filter(title_q).distinct().select_related()[0]
            if page:
                langs = page.get_languages() 
                if lang in langs:
                    return page, None
                else:
                    path = None
                    for alt_lang in get_fallback_languages(lang):
                        if alt_lang in langs:
                            path = '/%s%s' % (alt_lang, page.get_absolute_url(language=lang, fallback=True))
                            return None, path
                    return None, path
    except IndexError:
        return None, None
Beispiel #3
0
def assign_plugins(request, placeholders, lang=None):
    """
    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
    if hasattr(request, "current_page") and request.current_page is not None:
        languages = request.current_page.get_languages()
        if not lang in languages and not get_redirect_on_fallback(lang):
            fallbacks = get_fallback_languages(lang)
            for fallback in fallbacks:
                if fallback in languages:
                    request_lang = fallback
                    break
                    # get all plugins for the given placeholders
    qs = get_cmsplugin_queryset(request).filter(placeholder__in=placeholders, language=request_lang).order_by(
        'placeholder', 'tree_id', 'lft')
    plugin_list = downcast_plugins(qs)

    # 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, '_%s_plugins_cache' % lang, list(groups.get(placeholder.pk, [])))
Beispiel #4
0
def get_fallback_language(language):
    try:
        language_list = get_fallback_languages(language)
        if len(language_list) > 0:
            return language_list[0]
    except:
        return None
Beispiel #5
0
    def get_nodes(self, request):
        page_queryset = get_page_queryset(request)
        site = current_site(request)
        lang = get_language_from_request(request)

        filters = {
            'site': site,
        }
        if hide_untranslated(lang, site.pk):
            filters['title_set__language'] = lang
            if not use_draft(request):
                filters['title_set__published'] = True

        if not use_draft(request):
            page_queryset = page_queryset.published()
        pages = page_queryset.filter(**filters).order_by("path")
        ids = {}
        nodes = []
        first = True
        home_cut = False
        home_children = []
        home = None
        actual_pages = []

        # cache view perms
        visible_pages = get_visible_pages(request, pages, site)
        for page in pages:
            # Pages are ordered by path, therefore the first page is the root
            # of the page tree (a.k.a "home")
            if page.pk not in visible_pages:
                # Don't include pages the user doesn't have access to
                continue
            if not home:
                home = page
            if first and page.pk != home.pk:
                home_cut = True
            if (home_cut and (page.parent_id == home.pk or 
                    page.parent_id in home_children)):
                home_children.append(page.pk)
            if ((page.pk == home.pk and home.in_navigation)
                    or page.pk != home.pk):
                first = False
            ids[page.id] = page
            actual_pages.append(page)
            page.title_cache = {}

        langs = [lang]
        if not hide_untranslated(lang):
            langs.extend(get_fallback_languages(lang))

        titles = list(get_title_queryset(request).filter(
            page__in=ids, language__in=langs))
        for title in titles:  # add the title and slugs and some meta data
            page = ids[title.page_id]
            page.title_cache[title.language] = title

        for page in actual_pages:
            if page.title_cache:
                nodes.append(page_to_node(page, home, home_cut))
        return nodes
 def _get_title_cache(self, language, fallback, version_id, force_reload):
     if not language:
         language = get_language()
     load = False
     if not hasattr(self, "title_cache") or force_reload:
         load = True
         self.title_cache = {}
     elif not language in self.title_cache:
         if fallback:
             fallback_langs = get_fallback_languages(language)
             for lang in fallback_langs:
                 if lang in self.title_cache:
                     return lang    
         load = True 
     if load:
         from cms.models.titlemodels import Title
         if version_id:
             from reversion.models import Version
             version = get_object_or_404(Version, pk=version_id)
             revs = [related_version.object_version for related_version in version.revision.version_set.all()]
             for rev in revs:
                 obj = rev.object
                 if obj.__class__ == Title:
                     self.title_cache[obj.language] = obj
         else:
             title = Title.objects.get_title(self, language, language_fallback=fallback)
             if title:
                 self.title_cache[title.language] = title 
             language = title.language
     return language
Beispiel #7
0
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):
                fallbacks = get_fallback_languages(lang)
                for fallback_language in fallbacks:
                    assign_plugins(request, [placeholder],
                                   template,
                                   fallback_language,
                                   no_fallback=True)
                    plugins = placeholder._plugins_cache
                    if 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, [])))
Beispiel #8
0
    def get_nodes(self, request):
        page_queryset = get_page_queryset(request)
        site = Site.objects.get_current()
        lang = get_language_from_request(request)

        filters = {
            'site': site,
        }

        if hide_untranslated(lang, site.pk):
            filters['title_set__language'] = lang

        if not use_draft(request):
            page_queryset = page_queryset.published(lang)
        pages = page_queryset.filter(**filters).order_by("tree_id", "lft")
        ids = {}
        nodes = []
        first = True
        home_cut = False
        home_children = []
        home = None
        actual_pages = []

        # cache view perms
        visible_pages = get_visible_pages(request, pages, site)
        for page in pages:
            # Pages are ordered by tree_id, therefore the first page is the root
            # of the page tree (a.k.a "home")
            if page.pk not in visible_pages:
                # Don't include pages the user doesn't have access to
                continue
            if not home:
                home = page
            if first and page.pk != home.pk:
                home_cut = True
            if (page.parent_id == home.pk or page.parent_id in home_children) and home_cut:
                home_children.append(page.pk)
            if (page.pk == home.pk and home.in_navigation) or page.pk != home.pk:
                first = False
            ids[page.id] = page
            actual_pages.append(page)
            page.title_cache = {}

        langs = [lang]
        if not hide_untranslated(lang):
            langs.extend(get_fallback_languages(lang))

        titles = list(get_title_queryset(request).filter(page__in=ids, language__in=langs))
        for title in titles: # add the title and slugs and some meta data
            page = ids[title.page_id]
            page.title_cache[title.language] = title

        for page in actual_pages:
            if page.title_cache:
                nodes.append(page_to_node(page, home, home_cut))
        return nodes
Beispiel #9
0
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 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
Beispiel #11
0
 def get_nodes(self, request):
     page_queryset = get_page_queryset(request)
     site = Site.objects.get_current()
     lang = get_language_from_request(request)
     filters = {
         'site':site,
     }
     if settings.CMS_HIDE_UNTRANSLATED:
         filters['title_set__language'] = lang
     pages = page_queryset.published().filter(**filters).order_by("tree_id", "lft")
     ids = []
     nodes = []
     first = True
     home_cut = False
     home_children = []
     home = None
     for page in pages:
         if not home:
             home = page
         
         page.home_pk_cache = home.pk
         if first and page.pk != home.pk:
             home_cut = True
         if (page.parent_id == home.pk or page.parent_id in home_children) and home_cut:
             page.home_cut_cache = True 
             home_children.append(page.pk)
         if (page.pk == home.pk and home.in_navigation) or page.pk != home.pk:
             first = False
         ids.append(page.id)
     titles = list(get_title_queryset(request).filter(page__in=ids, language=lang))
     for page in pages:# add the title and slugs and some meta data
         for title in titles:
             if title.page_id == page.pk:
                 if not hasattr(page, "title_cache"):
                     page.title_cache = {}
                 page.title_cache[title.language] = title
                 nodes.append(page_to_node(page, home, home_cut))
                 ids.remove(page.pk)
     if ids: # get fallback languages
         fallbacks = get_fallback_languages(lang)
         for l in fallbacks:
             titles = list(get_title_queryset(request).filter(page__in=ids, language=l))
             for title in titles:
                 for page in pages:# add the title and slugs and some meta data
                     if title.page_id == page.pk:
                         if not hasattr(page, "title_cache"):
                             page.title_cache = {}
                         page.title_cache[title.language] = title
                         nodes.append(page_to_node(page, home, home_cut))
                         ids.remove(page.pk)
                         break
             if not ids:
                 break
     return nodes  
Beispiel #12
0
 def get_nodes(self, request):
     page_queryset = get_page_queryset(request)
     site = Site.objects.get_current()
     lang = get_language_from_request(request)
     filters = {
         'site':site,
     }
     if settings.CMS_HIDE_UNTRANSLATED:
         filters['title_set__language'] = lang
     pages = page_queryset.published().filter(**filters).order_by("tree_id", "lft")
     ids = []
     nodes = []
     first = True
     home_cut = False
     home_children = []
     home = None
     for page in pages:
         if not home:
             home = page
         
         page.home_pk_cache = home.pk
         if first and page.pk != home.pk:
             home_cut = True
         if (page.parent_id == home.pk or page.parent_id in home_children) and home_cut:
             page.home_cut_cache = True 
             home_children.append(page.pk)
         if (page.pk == home.pk and home.in_navigation) or page.pk != home.pk:
             first = False
         ids.append(page.id)
     titles = list(get_title_queryset(request).filter(page__in=ids, language=lang))
     for page in pages:# add the title and slugs and some meta data
         for title in titles:
             if title.page_id == page.pk:
                 if not hasattr(page, "title_cache"):
                     page.title_cache = {}
                 page.title_cache[title.language] = title
                 nodes.append(page_to_node(page, home, home_cut))
                 ids.remove(page.pk)
     if ids: # get fallback languages
         fallbacks = get_fallback_languages(lang)
         for l in fallbacks:
             titles = list(get_title_queryset(request).filter(page__in=ids, language=l))
             for title in titles:
                 for page in pages:# add the title and slugs and some meta data
                     if title.page_id == page.pk:
                         if not hasattr(page, "title_cache"):
                             page.title_cache = {}
                         page.title_cache[title.language] = title
                         nodes.append(page_to_node(page, home, home_cut))
                         ids.remove(page.pk)
                         break
             if not ids:
                 break
     return nodes  
Beispiel #13
0
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'))
    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)):
        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)
    # 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')))
    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:
        setattr(placeholder, '_plugins_cache', groups.get(placeholder.pk, []))
Beispiel #14
0
    def __getattr__(self, attr):
        current_lang = get_language()
        lang_attr = attr + '_' + current_lang

        if lang_attr in self.__dict__:
            return self.__dict__[lang_attr]

        for lang in get_fallback_languages(current_lang):
            lang_attr = attr + '_' + lang
            if lang_attr in self.__dict__:
                return self.__dict__[lang_attr]

        # secondary_attrs=self.get_secondary_attributes()
        # if attr in secondary_attrs:
        #     return getattr(self.eav, attr)
        #
        # lang_attr=attr+'_'+current_lang
        # if lang_attr in secondary_attrs:
        #         return getattr(self.eav, lang_attr)
        #
        # for lang in get_fallback_languages(current_lang):
        #     lang_attr=attr+'_'+lang
        #     if lang_attr in secondary_attrs:
        #         return getattr(self.eav, lang_attr)
        if attr == '_position_in_list_cache':  #for position field
            raise AttributeError
        if attr[-2:] == '_m':
            lang_attr = attr[:-2] + '_' + current_lang
            try:
                return getattr(self.eav, lang_attr)
            except AttributeError:
                for lang in get_fallback_languages(current_lang):
                    lang_attr = attr[:-2] + '_' + lang
                    try:
                        return getattr(self.eav, lang_attr)
                    except AttributeError:
                        pass
                return ''
        else:
            return getattr(self.eav, attr)
Beispiel #15
0
def get_teaser(self,
               language=None,
               fallback=True,
               version_id=None,
               force_reload=False):
    """
    Get the teaser of the page depending on the given language
    """
    # This is based largely off of ``cms.models.Page.get_title``
    # but it doesn't bother with revisions and flattens out
    # the logic in ``get_title_obj_attribute``,
    # ``get_title_obj`` and ``_get_title_cache`` into a single
    # method
    if not language:
        language = get_language()
    load = False
    if not hasattr(self, 'teaser_cache') or force_reload:
        # No teasers have been cached. We need to load the
        # teaser from the database
        load = True
        # But first, create the cache attribute
        self.teaser_cache = {}
    elif not language in self.teaser_cache:
        # We have the cache set up, but the desired language
        # isn't cached.
        if fallback:
            # Check if we've cached the teaser in a fallback
            # language
            fallback_langs = i18n.get_fallback_languages(language)
            for lang in fallback_langs:
                if lang in self.teaser_cache:
                    # We found a teaser for the fallback
                    # language.  Return it!
                    return self.teaser_cache[lang].teaser
            # We didn't find teasers in any fallback language,
            # We'll try to load it from the database below
            load = True

    if load:
        # Use ``TeaserManager.get_teaser`` to handle
        # getting the ``Teaser`` instance from the database
        # wth language fallback
        teaser = Teaser.objects.get_teaser(self,
                                           language,
                                           language_fallback=fallback)
        if teaser:
            # We found a teaser. Cache it and then return it
            self.teaser_cache[teaser.language] = teaser
            return teaser.teaser

    # If all else fails, return an empty string
    return ""
Beispiel #16
0
def get_alternate(page, site=None, site_languages=None, protocol=None,
                  enable_redirectors=None):
    # Optimize for repeated calls within the same site
    if site is None:
        site = Site.objects.get_current()
    if site_languages is None:
        site_languages = get_public_languages(site.pk)
    # TODO: build API for this default
    if enable_redirectors is None:
       enable_redirectors = get_config_redirectors()

    protocol = protocol if protocol is not None else 'http'

    # find all public translations for this page
    available_languages = {l for l in page.get_languages()
                           if l in site_languages}
    sitemap_languages = [l for l in site_languages
                         if l in available_languages]

    # handle case when hide_untranslated = False
    if len(sitemap_languages) < len(site_languages):
        for lang in site_languages:
            if (lang not in sitemap_languages
                and not hide_untranslated(lang, site.pk)):
                for fb_lang in sitemap_languages:
                    if fb_lang in get_fallback_languages(lang, site.pk):
                        sitemap_languages.append(lang)
                        break

    # Append default redirector link
    if sitemap_languages and enable_redirectors:
        sitemap_languages.append(LANG_REDIRECTOR)

    alt_links = OrderedDict()

    for lang in sitemap_languages:
        if lang == LANG_REDIRECTOR:
            with override(sitemap_languages[0]):
                url = page.get_absolute_url()
            url = re.sub(r'^/{}'.format(sitemap_languages[0]), '', url)
            assert sitemap_languages[0] != LANG_REDIRECTOR
        else:
            with override(lang):
                url = page.get_absolute_url()
        alt_links[lang] = {'language_code': lang,
                           'location': '%s://%s%s' % (protocol,
                                                      site.domain,
                                                      url),
                           'redirector': lang == LANG_REDIRECTOR,
                           'path': url}
    return alt_links
Beispiel #17
0
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, [])))
Beispiel #18
0
def update_site_and_page_choices(lang=None):
    lang = lang or i18n.get_current_language()
    SITE_CHOICES_KEY = get_site_cache_key(lang)
    PAGE_CHOICES_KEY = get_page_cache_key(lang)
    title_queryset = (Title.objects.drafts()
    .select_related('page', 'page__site')
    .order_by('page__tree_id', 'page__lft', 'page__rght'))
    pages = defaultdict(SortedDict)
    sites = {}
    for title in title_queryset:
        page = pages[title.page.site.pk].get(title.page.pk, {})
        page[title.language] = title
        pages[title.page.site.pk][title.page.pk] = page
        sites[title.page.site.pk] = title.page.site.name

    site_choices = []
    page_choices = [('', '----')]

    try:
        fallbacks = i18n.get_fallback_languages(lang)
    except LanguageError:
        fallbacks = []
    language_order = [lang] + fallbacks

    for sitepk, sitename in sites.items():
        site_choices.append((sitepk, sitename))

        site_page_choices = []
        for titles in pages[sitepk].values():
            title = None
            for language in language_order:
                title = titles.get(language)
                if title:
                    break
            if not title:
                continue

            indent = u"&nbsp;&nbsp;" * title.page.level
            page_title = mark_safe(u"%s%s" % (indent, title.title))
            site_page_choices.append((title.page.pk, page_title))

        page_choices.append((sitename, site_page_choices))
    from django.core.cache import cache
    # We set it to 1 day here because we actively invalidate this cache.
    cache.set(SITE_CHOICES_KEY, site_choices, 86400)
    cache.set(PAGE_CHOICES_KEY, page_choices, 86400)
    return site_choices, page_choices
Beispiel #19
0
def update_site_and_page_choices(lang=None):
    lang = lang or translation.get_language()
    SITE_CHOICES_KEY = get_site_cache_key(lang)
    PAGE_CHOICES_KEY = get_page_cache_key(lang)
    if settings.CMS_MODERATOR:
        title_queryset = Title.objects.filter(page__publisher_is_draft=False)
    else:
        title_queryset = Title.objects.filter(page__publisher_is_draft=True)
    title_queryset = title_queryset.select_related(
        'page', 'page__site').order_by('page__tree_id', 'page__lft',
                                       'page__rght')
    pages = defaultdict(SortedDict)
    sites = {}
    for title in title_queryset:
        page = pages[title.page.site.pk].get(title.page.pk, {})
        page[title.language] = title
        pages[title.page.site.pk][title.page.pk] = page
        sites[title.page.site.pk] = title.page.site.name

    site_choices = []
    page_choices = [('', '----')]

    language_order = [lang] + i18n.get_fallback_languages(lang)

    for sitepk, sitename in sites.items():
        site_choices.append((sitepk, sitename))

        site_page_choices = []
        for titles in pages[sitepk].values():
            title = None
            for language in language_order:
                title = titles.get(language)
                if title:
                    break
            if not title:
                continue

            indent = u"&nbsp;&nbsp;" * title.page.level
            page_title = mark_safe(u"%s%s" % (indent, title.title))
            site_page_choices.append((title.page.pk, page_title))

        page_choices.append((sitename, site_page_choices))

    # We set it to 1 day here because we actively invalidate this cache.
    cache.set(SITE_CHOICES_KEY, site_choices, 86400)
    cache.set(PAGE_CHOICES_KEY, page_choices, 86400)
    return site_choices, page_choices
Beispiel #20
0
def update_site_and_page_choices(lang=None):
    lang = lang or translation.get_language()
    SITE_CHOICES_KEY = get_site_cache_key(lang)
    PAGE_CHOICES_KEY = get_page_cache_key(lang)
    if settings.CMS_MODERATOR:
        title_queryset = Title.objects.filter(page__publisher_is_draft=False)
    else:
        title_queryset = Title.objects.filter(page__publisher_is_draft=True)
    title_queryset = title_queryset.select_related("page", "page__site").order_by(
        "page__tree_id", "page__lft", "page__rght"
    )
    pages = defaultdict(SortedDict)
    sites = {}
    for title in title_queryset:
        page = pages[title.page.site.pk].get(title.page.pk, {})
        page[title.language] = title
        pages[title.page.site.pk][title.page.pk] = page
        sites[title.page.site.pk] = title.page.site.name

    site_choices = []
    page_choices = [("", "----")]

    language_order = [lang] + i18n.get_fallback_languages(lang)

    for sitepk, sitename in sites.items():
        site_choices.append((sitepk, sitename))

        site_page_choices = []
        for titles in pages[sitepk].values():
            title = None
            for language in language_order:
                title = titles.get(language)
                if title:
                    break
            if not title:
                continue

            indent = u"&nbsp;&nbsp;" * title.page.level
            page_title = mark_safe(u"%s%s" % (indent, title.title))
            site_page_choices.append((title.page.pk, page_title))

        page_choices.append((sitename, site_page_choices))

    # We set it to 1 day here because we actively invalidate this cache.
    cache.set(SITE_CHOICES_KEY, site_choices, 86400)
    cache.set(PAGE_CHOICES_KEY, page_choices, 86400)
    return site_choices, page_choices
Beispiel #21
0
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'))
    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)):
        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, []))
Beispiel #22
0
def get_teaser(self, language=None, fallback=True, version_id=None, force_reload=False):
    """
    Get the teaser of the page depending on the given language
    """
    # This is based largely off of ``cms.models.Page.get_title``
    # but it doesn't bother with revisions and flattens out
    # the logic in ``get_title_obj_attribute``,
    # ``get_title_obj`` and ``_get_title_cache`` into a single
    # method
    if not language:
        language = get_language()
    load = False
    if not hasattr(self, 'teaser_cache') or force_reload:
        # No teasers have been cached. We need to load the
        # teaser from the database
        load = True
        # But first, create the cache attribute
        self.teaser_cache = {}
    elif not language in self.teaser_cache:
        # We have the cache set up, but the desired language
        # isn't cached.
        if fallback:
            # Check if we've cached the teaser in a fallback
            # language
            fallback_langs = i18n.get_fallback_languages(language)
            for lang in fallback_langs:
                if lang in self.teaser_cache:
                    # We found a teaser for the fallback
                    # language.  Return it!
                    return self.teaser_cache[lang].teaser
            # We didn't find teasers in any fallback language,
            # We'll try to load it from the database below
            load = True

    if load:
        # Use ``TeaserManager.get_teaser`` to handle
        # getting the ``Teaser`` instance from the database
        # wth language fallback
        teaser = Teaser.objects.get_teaser(self, language, language_fallback=fallback)
        if teaser:
            # We found a teaser. Cache it and then return it
            self.teaser_cache[teaser.language] = teaser
            return teaser.teaser

    # If all else fails, return an empty string
    return ""
Beispiel #23
0
def get_current_page(path, lang, queryset, home_slug=None, home_tree_id=None):
    """Helper for getting current page from path depending on language
    
    returns: (Page, None) or (None, path_to_alternative language)
    """
    try:
        if settings.CMS_FLAT_URLS:
            title_q = Q(title_set__slug=path)
            return queryset.filter(title_q & Q(
                title_set__language=lang)).distinct().select_related()[0], None
        else:
            if home_slug:
                #queryset = queryset.exclude(Q(title_set__path=home_slug)&Q(tree_id=home_tree_id))
                home_slug += "/"
                title_q = Q(title_set__path=path) | (
                    Q(title_set__path=home_slug + path)
                    & Q(tree_id=home_tree_id))
            else:
                title_q = Q(title_set__slug=path)
            if settings.CMS_DBGETTEXT and settings.CMS_DBGETTEXT_SLUGS:
                # ugly hack -- brute force search for reverse path translation:
                from django.utils.translation import ugettext
                from cms.models import Title
                for t in Title.objects.all():
                    tpath = '/'.join([ugettext(x) for x in t.path.split('/')])
                    if path == tpath:
                        title_q = Q(title_set__path=t.path)
                        break
            page = queryset.filter(title_q).distinct().select_related()[0]
            if page:
                langs = page.get_languages()
                if lang in langs or settings.CMS_DBGETTEXT:
                    return page, None
                else:
                    path = None
                    for alt_lang in get_fallback_languages(lang):
                        if alt_lang in langs:
                            path = '/%s%s' % (alt_lang,
                                              page.get_absolute_url(
                                                  language=lang,
                                                  fallback=True))
                            return None, path
                    return None, path
    except IndexError:
        return None, None
Beispiel #24
0
    def known_translation_getter(self,
                                 field,
                                 default=None,
                                 language_code=None,
                                 any_language=False):
        """
        This is meant to act like HVAD/Parler's safe_translation_getter() but
        respects the fallback preferences as defined in
        `settings.CMS_LANGUAGES` and returns both the translated field value
        and the language it represents as a tuple: (value, language).

        If no suitable language is found, then it returns (default, None)
        """
        # NOTE: We're using the CMS fallbacks here, rather than the Parler
        # fallbacks, the developer should ensure that their project's Parler
        # settings match the CMS settings.
        try:
            object_languages = self.get_available_languages()
            assert hasattr(object_languages, '__iter__')
        except [KeyError, AssertionError]:
            raise ImproperlyConfigured(
                "TranslationHelperMixin must be used with a model defining"
                "get_available_languages() that returns a list of available"
                "language codes. E.g., django-parler's TranslatableModel.")

        language_code = (language_code or get_current_language()
                         or get_default_language())
        site_id = getattr(settings, 'SITE_ID', None)
        languages = [language_code] + get_fallback_languages(language_code,
                                                             site_id=site_id)

        # Grab the first language that is common to our list of fallbacks and
        # the list of available languages for this object.
        if languages and object_languages:
            language_code = next(
                (lang for lang in languages if lang in object_languages), None)

            if language_code:
                value = self.safe_translation_getter(
                    field, default=default, language_code=language_code)
                return (value, language_code)

        # No suitable translation exists
        return (default, None)
Beispiel #25
0
    def get_direct_related_page_extensions(
        self, extension_model, plugin_model, language=None
    ):
        """
        Return the page extensions linked to this page via a plugin in a placeholder, ranked by
        their `path` to respect the order in the page tree.
        """
        current_language = language or translation.get_language()
        site = get_current_site()

        languages = [current_language] + i18n.get_fallback_languages(
            current_language, site_id=site.pk
        )
        existing_languages = (
            plugin_model.objects.filter(
                cmsplugin_ptr__placeholder__page=self.extended_object
            )
            .values_list("cmsplugin_ptr__language", flat=True)
            .distinct()
        )

        relevant_language = next(
            filter(lambda l: l in existing_languages, languages), current_language
        )

        related_name = plugin_model.page.field.related_query_name()
        selector = f"extended_object__{related_name:s}__cmsplugin_ptr"
        # pylint: disable=no-member
        filter_dict = {
            f"{selector:s}__language": relevant_language,
            f"{selector:s}__placeholder__page": self.extended_object,
        }
        # For a public course, we must filter out page extensions that are not published
        # in any language
        if self.extended_object.publisher_is_draft is False:
            filter_dict["extended_object__title_set__published"] = True

        return (
            extension_model.objects.filter(**filter_dict)
            .select_related("extended_object")
            .order_by("extended_object__node__path")
            .distinct()
        )
Beispiel #26
0
    def known_translation_getter(self, field, default=None,
                                 language_code=None, any_language=False):
        """
        This is meant to act like HVAD/Parler's safe_translation_getter() but
        respects the fallback preferences as defined in
        `settings.CMS_LANGUAGES` and returns both the translated field value
        and the language it represents as a tuple: (value, language).

        If no suitable language is found, then it returns (default, None)
        """
        # NOTE: We're using the CMS fallbacks here, rather than the Parler
        # fallbacks, the developer should ensure that their project's Parler
        # settings match the CMS settings.
        try:
            object_languages = self.get_available_languages()
            assert hasattr(object_languages, '__iter__')
        except [KeyError, AssertionError]:
            raise ImproperlyConfigured(
                "TranslationHelperMixin must be used with a model defining"
                "get_available_languages() that returns a list of available"
                "language codes. E.g., django-parler's TranslatableModel.")

        language_code = (
            language_code or get_current_language() or get_default_language())
        site_id = getattr(settings, 'SITE_ID', None)
        languages = [language_code] + get_fallback_languages(
            language_code, site_id=site_id)

        # Grab the first language that is common to our list of fallbacks and
        # the list of available languages for this object.
        if languages and object_languages:
            language_code = next(
                (lang for lang in languages if lang in object_languages), None)

            if language_code:
                value = self.safe_translation_getter(field,
                    default=default, language_code=language_code)
                return (value, language_code)

        # No suitable translation exists
        return (default, None)
Beispiel #27
0
    def get_page_path(self, lang):
        page = getattr(self.request, 'current_page', None)

        if not page:
            return '/%s/' % lang if settings.USE_I18N else '/'

        page_languages = page.get_published_languages()

        if lang in page_languages:
            return page.get_absolute_url(lang, fallback=False)

        site = get_current_site()

        if is_valid_site_language(lang, site_id=site.pk):
            _valid_language = True
            _hide_untranslated = hide_untranslated(lang, site.pk)
        else:
            _valid_language = False
            _hide_untranslated = False

        if _hide_untranslated and settings.USE_I18N:
            return '/%s/' % lang

        default_language = get_default_language_for_site(site.pk)

        if not _valid_language and default_language in page_languages:
            # The request language is not configured for the current site.
            # Fallback to the default language configured for the current site.
            return page.get_absolute_url(default_language, fallback=False)

        if _valid_language:
            fallbacks = get_fallback_languages(lang, site_id=site.pk) or []
            fallbacks = [
                _lang for _lang in fallbacks if _lang in page_languages
            ]
        else:
            fallbacks = []

        if fallbacks:
            return page.get_absolute_url(fallbacks[0], fallback=False)
        return '/%s/' % lang if settings.USE_I18N else '/'
Beispiel #28
0
def get_plugin_language_fallback_clause(language, is_draft):
    """
    Return a language fallback clause to apply in more complex queries where we
    select plugins and need to apply language fallbacks.
    """
    site = get_current_site()
    languages = [language] + i18n.get_fallback_languages(language,
                                                         site_id=site.pk)
    languages = list(dict.fromkeys(languages))

    for item in range(len(languages)):
        for previous_item, previous_language in enumerate(languages[:item +
                                                                    1]):

            qop_dict = {
                "extended_object__placeholders__cmsplugin__language":
                previous_language
            }
            if previous_item == item:
                if not is_draft:
                    qop_dict.update({
                        "extended_object__title_set__language":
                        previous_language,
                        "extended_object__title_set__published":
                        True,
                    })
                qop = models.Q(**qop_dict)
            else:
                qop = ~models.Q(**qop_dict)

            if previous_item == 0:
                subclause = qop
            else:
                subclause &= qop

        if item == 0:
            language_clause = subclause
        else:
            language_clause |= subclause

    return language_clause
Beispiel #29
0
 def get_title(self, page, language, language_fallback=False):
     """
     Gets the latest content for a particular page and language. Falls back
     to another language if wanted.
     """
     try:
         title = self.get(language=language, page=page)
         return title
     except self.model.DoesNotExist:
         if language_fallback:
             try:
                 titles = self.filter(page=page)
                 fallbacks = get_fallback_languages(language)
                 for l in fallbacks:
                     for title in titles:
                         if l == title.language:
                             return title
                 return None
             except self.model.DoesNotExist:
                 pass
     return None        
Beispiel #30
0
def get_current_page(path, lang, queryset, home_slug=None, home_tree_id=None):
    """Helper for getting current page from path depending on language
    
    returns: (Page, None) or (None, path_to_alternative language)
    """
    try:
        if settings.CMS_FLAT_URLS:
            title_q = Q(title_set__slug=path)
            return queryset.filter(title_q & Q(title_set__language=lang)).distinct().select_related()[0], None
        else:
            if home_slug:
                queryset = queryset.exclude(Q(title_set__path=home_slug)&Q(tree_id=home_tree_id))
                home_slug += "/"
                title_q = Q(title_set__path=path)|(Q(title_set__path=home_slug + path)&Q(tree_id=home_tree_id))
            else:
                title_q = Q(title_set__slug=path)
            if settings.CMS_DBGETTEXT and settings.CMS_DBGETTEXT_SLUGS:
                # ugly hack -- brute force search for reverse path translation:
                from django.utils.translation import ugettext
                from cms.models import Title
                for t in Title.objects.all():
                    tpath = '/'.join([ugettext(x) for x in t.path.split('/')])
                    if path == tpath:
                        title_q = Q(title_set__path=t.path)
                        break
            page = queryset.filter(title_q).distinct().select_related()[0]
            if page:
                langs = page.get_languages() 
                if lang in langs or settings.CMS_DBGETTEXT:
                    return page, None
                else:
                    path = None
                    for alt_lang in get_fallback_languages(lang):
                        if alt_lang in langs:
                            path = '/%s%s' % (alt_lang, page.get_absolute_url(language=lang, fallback=True))
                            return None, path
                    return None, path
    except IndexError:
        return None, None
Beispiel #31
0
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, []))
Beispiel #32
0
 def get_title(self, page, language, language_fallback=False):
     """
     Gets the latest content for a particular page and language. Falls back
     to another language if wanted.
     """
     try:
         title = self.get(language=language, page=page)
         return title
     except self.model.DoesNotExist:
         if language_fallback:
             try:
                 titles = self.filter(page=page)
                 fallbacks = get_fallback_languages(language)
                 for lang in fallbacks:
                     for title in titles:
                         if lang == title.language:
                             return title
                 return None
             except self.model.DoesNotExist:
                 pass
         else:
             raise
     return None
Beispiel #33
0
 def get_teaser(self, page, language, language_fallback=False):
     """
     Gets the latest content for a particular page and language. Falls back
     to another language if wanted.
     """
     try:
         teaser = self.get(language=language, page=page)
         return teaser
     except self.model.DoesNotExist:
         if language_fallback:
             try:
                 teasers = self.filter(page=page)
                 fallbacks = get_fallback_languages(language)
                 for lang in fallbacks:
                     for teaser in teasers:
                         if lang == teaser.language:
                             return teaser
                 return None
             except self.model.DoesNotExist:
                 pass
         else:
             raise
     return None
Beispiel #34
0
    def _get_title_cache(self, language, fallback, version_id, force_reload):
        if not language:
            language = get_language()
        load = False
        if not hasattr(self, "title_cache") or force_reload:
            load = True
            self.title_cache = {}
        elif not language in self.title_cache:
            if fallback:
                fallback_langs = i18n.get_fallback_languages(language)
                for lang in fallback_langs:
                    if lang in self.title_cache:
                        return lang
            load = True
        if load:
            from cms.models.titlemodels import Title

            if version_id:
                from reversion.models import Version

                version = get_object_or_404(Version, pk=version_id)
                revs = [
                    related_version.object_version
                    for related_version in version.revision.version_set.all()
                ]
                for rev in revs:
                    obj = rev.object
                    if obj.__class__ == Title:
                        self.title_cache[obj.language] = obj
            else:
                title = Title.objects.get_title(self,
                                                language,
                                                language_fallback=fallback)
                if title:
                    self.title_cache[title.language] = title
                language = title.language
        return language
Beispiel #35
0
def get_current_page(path, lang, queryset, home_slug, home_tree_id):
    """Helper for getting current page from path depending on language
    
    returns: (Page, None) or (None, path_to_alternative language)
    """
    try:
        if settings.CMS_FLAT_URLS:
            title_q = Q(title_set__slug=path)
            return queryset.filter(title_q & Q(
                title_set__language=lang)).distinct().select_related()[0], None
        else:
            if home_slug:
                queryset = queryset.exclude(
                    Q(title_set__path=home_slug) & Q(tree_id=home_tree_id))
                home_slug += "/"
                title_q = Q(title_set__path=path) | (
                    Q(title_set__path=home_slug + path)
                    & Q(tree_id=home_tree_id))
            else:
                title_q = Q(title_set__slug=path)
            page = queryset.filter(title_q).distinct().select_related()[0]
            if page:
                langs = page.get_languages()
                if lang in langs:
                    return page, None
                else:
                    path = None
                    for alt_lang in get_fallback_languages(lang):
                        if alt_lang in langs:
                            path = '/%s%s' % (alt_lang,
                                              page.get_absolute_url(
                                                  language=lang,
                                                  fallback=True))
                            return None, path
                    return None, path
    except IndexError:
        return None, None
Beispiel #36
0
def details(request, slug):
    """
    The main view of the Django-CMS! Takes a request and a slug, renders the
    page.
    """
    # get the right model
    context = RequestContext(request)
    # Get a Page model object from the request
    page = get_page_from_request(request, use_path=slug)
    if not page:
        return _handle_no_page(request, slug)
    
    current_language = get_language_from_request(request)
    
    # Check that the current page is available in the desired (current) language
    available_languages = page.get_languages()
    
    # We resolve an alternate language for the page if it's not available.
    # Since the "old" details view had an exception for the root page, it is
    # ported here. So no resolution if the slug is ''.
    if (current_language not in available_languages) and (slug != ''):
        if settings.CMS_LANGUAGE_FALLBACK:
            # If we didn't find the required page in the requested (current) 
            # language, let's try to find a suitable fallback in the list of 
            # fallback languages (CMS_LANGUAGE_CONF)
            for alt_lang in get_fallback_languages(current_language):
                if alt_lang in available_languages:
                    alt_url = page.get_absolute_url(language=alt_lang, fallback=True)
                    path = '/%s%s' % (alt_lang, alt_url)
                    # In the case where the page is not available in the
                    # preferred language, *redirect* to the fallback page. This
                    # is a design decision (instead of rendering in place)).
                    return HttpResponseRedirect(path)
        # There is a page object we can't find a proper language to render it 
        _handle_no_page(request, slug)

    if apphook_pool.get_apphooks():
        # There are apphooks in the pool. Let's see if there is one for the
        # current page
        # since we always have a page at this point, applications_page_check is
        # pointless
        # page = applications_page_check(request, page, slug)
        # Check for apphooks! This time for real!
        app_urls = page.get_application_urls(current_language, False)
        if app_urls:
            app = apphook_pool.get_apphook(app_urls)
            pattern_list = []
            for urlpatterns in get_app_urls(app.urls):
                pattern_list += urlpatterns
            urlpatterns = patterns('', *pattern_list)
            try:
                view, args, kwargs = resolve('/', tuple(urlpatterns))
                return view(request, *args, **kwargs)
            except Resolver404:
                pass

    # Check if the page has a redirect url defined for this language. 
    redirect_url = page.get_redirect(language=current_language)
    if redirect_url:
        if settings.i18n_installed and redirect_url[0] == "/":
            redirect_url = "/%s/%s" % (current_language, redirect_url.lstrip("/"))
        # add language prefix to url
        return HttpResponseRedirect(redirect_url)
    
    # permission checks
    if page.login_required and not request.user.is_authenticated():
        if settings.i18n_installed:
            path = urlquote("/%s%s" % (request.LANGUAGE_CODE, request.get_full_path()))
        else:
            path = urlquote(request.get_full_path())
        tup = django_settings.LOGIN_URL , "next", path
        return HttpResponseRedirect('%s?%s=%s' % tup)

    if page.login_required and not page.has_view_permission(request):
        return HttpResponseForbidden("You don't have the rights to access this resource")
    
    template_name = get_template_from_request(request, page, no_current_page=True)
    # fill the context 
    context['lang'] = current_language
    context['current_page'] = page
    context['has_change_permissions'] = page.has_change_permission(request)
    return render_to_response(template_name, context)
Beispiel #37
0
def get_public_page_with_fallbacks(page, request):
    """
    the plugin should show the published page whenever it exists or the draft page otherwise.

    On a public content, the draft page should not be shown at all but this is left to the
    caller.

    This is inspired by what DjangoCMS does in its main view:
    https://github.com/django-cms/django-cms/blob/3.8.0/cms/views.py#L37
    """
    page = page.get_public_object()
    request_language = translation.get_language_from_request(request,
                                                             check_path=True)

    if not page:
        return None

    # Check permissions
    site = get_current_site()
    if not page_permissions.user_can_view_page(request.user, page, site):
        return None

    if request.user.is_staff:
        user_languages = i18n.get_language_list(site_id=site.pk)
    else:
        user_languages = i18n.get_public_languages(site_id=site.pk)

    # These languages are then filtered out by the user allowed languages
    available_languages = [
        language for language in user_languages
        if language in list(page.get_published_languages())
    ]

    if request_language not in user_languages:
        # Language is not allowed
        # Use the default site language
        default_language = i18n.get_default_language_for_site(site.pk)
        fallbacks = i18n.get_fallback_languages(default_language,
                                                site_id=site.pk)
        fallbacks = [default_language] + fallbacks
    else:
        fallbacks = i18n.get_fallback_languages(request_language,
                                                site_id=site.pk)

    # Only fallback to languages the user is allowed to see
    fallback_languages = [
        language for language in fallbacks
        if language != request_language and language in available_languages
    ]

    if request_language not in available_languages:
        if not fallback_languages:
            # There is no page with the requested language
            # and there's no configured fallbacks
            return None
        if request_language in page.get_languages():
            # The page was already published and later unpublished in the current
            # language. In this case we must not fallback to another language.
            return None

    return page
Beispiel #38
0
def details(request, slug):
    """
    The main view of the Django-CMS! Takes a request and a slug, renders the
    page.
    """
    # get the right model
    context = RequestContext(request)
    # Get a Page model object from the request
    page = get_page_from_request(request, use_path=slug)
    if not page:
        return _handle_no_page(request, slug)

    current_language = get_language_from_request(request)
    # Check that the current page is available in the desired (current) language
    available_languages = []
    page_languages = list(page.get_languages())
    if hasattr(request, 'user') and request.user.is_staff:
        user_languages = get_language_list()
    else:
        user_languages = get_public_languages()
    for frontend_lang in user_languages:
        if frontend_lang in page_languages:
            available_languages.append(frontend_lang)
    attrs = ''
    if 'edit' in request.GET:
        attrs = '?edit=1'
    elif 'preview' in request.GET:
        attrs = '?preview=1'
        if 'draft' in request.GET:
            attrs += '&draft=1'
        # Check that the language is in FRONTEND_LANGUAGES:
    if not current_language in user_languages:
        #are we on root?
        if not slug:
            #redirect to supported language
            languages = []
            for language in available_languages:
                languages.append((language, language))
            if languages:
                with SettingsOverride(LANGUAGES=languages, LANGUAGE_CODE=languages[0][0]):
                    #get supported language
                    new_language = get_language_from_request(request)
                    if new_language in get_public_languages():
                        with force_language(new_language):
                            pages_root = reverse('pages-root')
                            return HttpResponseRedirect(pages_root + attrs)
            else:
                _handle_no_page(request, slug)
        else:
            return _handle_no_page(request, slug)
    if current_language not in available_languages:
        # If we didn't find the required page in the requested (current)
        # language, let's try to find a fallback
        found = False
        for alt_lang in get_fallback_languages(current_language):
            if alt_lang in available_languages:
                if get_redirect_on_fallback(current_language):
                    with force_language(alt_lang):
                        path = page.get_absolute_url(language=alt_lang, fallback=True)
                        # In the case where the page is not available in the
                    # preferred language, *redirect* to the fallback page. This
                    # is a design decision (instead of rendering in place)).
                    return HttpResponseRedirect(path + attrs)
                else:
                    found = True
        if not found:
            # There is a page object we can't find a proper language to render it
            _handle_no_page(request, slug)

    if apphook_pool.get_apphooks():
        # There are apphooks in the pool. Let's see if there is one for the
        # current page
        # since we always have a page at this point, applications_page_check is
        # pointless
        # page = applications_page_check(request, page, slug)
        # Check for apphooks! This time for real!
        try:
            app_urls = page.get_application_urls(current_language, False)
        except Title.DoesNotExist:
            app_urls = []
        if app_urls:
            app = apphook_pool.get_apphook(app_urls)
            pattern_list = []
            for urlpatterns in get_app_urls(app.urls):
                pattern_list += urlpatterns
            urlpatterns = patterns('', *pattern_list)
            try:
                view, args, kwargs = resolve('/', tuple(urlpatterns))
                return view(request, *args, **kwargs)
            except Resolver404:
                pass
                # Check if the page has a redirect url defined for this language.
    redirect_url = page.get_redirect(language=current_language)
    if redirect_url:
        if (is_language_prefix_patterns_used() and redirect_url[0] == "/"
        and not redirect_url.startswith('/%s/' % current_language)):
            # add language prefix to url
            redirect_url = "/%s/%s" % (current_language, redirect_url.lstrip("/"))
            # prevent redirect to self
        own_urls = [
            'http%s://%s%s' % ('s' if request.is_secure() else '', request.get_host(), request.path),
            '/%s' % request.path,
            request.path,
        ]
        if redirect_url not in own_urls:
            return HttpResponseRedirect(redirect_url + attrs)

    # permission checks
    if page.login_required and not request.user.is_authenticated():
        return redirect_to_login(urlquote(request.get_full_path()), settings.LOGIN_URL)

    template_name = get_template_from_request(request, page, no_current_page=True)
    # fill the context 
    context['lang'] = current_language
    context['current_page'] = page
    context['has_change_permissions'] = page.has_change_permission(request)
    context['has_view_permissions'] = page.has_view_permission(request)

    if not context['has_view_permissions']:
        return _handle_no_page(request, slug)

    return TemplateResponse(request, template_name, context)
Beispiel #39
0
    def get_nodes(self, request):
        page_queryset = get_page_queryset(request)
        site = Site.objects.get_current()
        lang = get_language_from_request(request)

        filters = {
            'site': site,
        }

        if settings.CMS_HIDE_UNTRANSLATED:
            filters['title_set__language'] = lang

        pages = page_queryset.published().filter(**filters).order_by(
            "tree_id", "lft")

        ids = []
        nodes = []
        first = True
        home_cut = False
        home_children = []
        home = None
        actual_pages = []

        # cache view perms
        visible_pages = get_visible_pages(request, pages, site)
        for page in pages:
            # Pages are ordered by tree_id, therefore the first page is the root
            # of the page tree (a.k.a "home")
            if page.pk not in visible_pages:
                # Don't include pages the user doesn't have access to
                continue
            if not home:
                home = page
            page.home_pk_cache = home.pk
            if first and page.pk != home.pk:
                home_cut = True
            if (page.parent_id == home.pk
                    or page.parent_id in home_children) and home_cut:
                home_children.append(page.pk)
            if (page.pk == home.pk
                    and home.in_navigation) or page.pk != home.pk:
                first = False
            ids.append(page.id)
            actual_pages.append(page)

        titles = list(
            get_title_queryset(request).filter(page__in=ids, language=lang))
        for page in actual_pages:  # add the title and slugs and some meta data
            for title in titles:
                if title.page_id == page.pk:
                    if not hasattr(page, "title_cache"):
                        page.title_cache = {}
                    page.title_cache[title.language] = title
                    nodes.append(page_to_node(page, home, home_cut))
                    ids.remove(page.pk)

        if ids:  # get fallback languages
            fallbacks = get_fallback_languages(lang)
            for l in fallbacks:
                titles = list(
                    get_title_queryset(request).filter(page__in=ids,
                                                       language=l))
                for title in titles:
                    for page in actual_pages:  # add the title and slugs and some meta data
                        if title.page_id == page.pk:
                            if not hasattr(page, "title_cache"):
                                page.title_cache = {}
                            page.title_cache[title.language] = title
                            nodes.append(page_to_node(page, home, home_cut))
                            ids.remove(page.pk)
                            break
                if not ids:
                    break
        return nodes
Beispiel #40
0
    def get_nodes(self, request):
        from cms.models import Title

        site = self.renderer.site
        lang = self.renderer.request_language
        pages = get_page_queryset(
            site,
            draft=self.renderer.draft_mode_active,
            published=not self.renderer.draft_mode_active,
        )

        if is_valid_site_language(lang, site_id=site.pk):
            _valid_language = True
            _hide_untranslated = hide_untranslated(lang, site.pk)
        else:
            _valid_language = False
            _hide_untranslated = False

        if _valid_language:
            # The request language has been explicitly configured
            # for the current site.
            if _hide_untranslated:
                fallbacks = []
            else:
                fallbacks = get_fallback_languages(lang, site_id=site.pk)
            languages = [lang
                         ] + [_lang for _lang in fallbacks if _lang != lang]
        else:
            # The request language is not configured for the current site.
            # Fallback to all configured public languages for the current site.
            languages = get_public_languages(site.pk)
            fallbacks = languages

        pages = (pages.filter(title_set__language__in=languages).
                 select_related('node').order_by('node__path').distinct())

        if not self.renderer.draft_mode_active:
            # we're dealing with public pages.
            # prefetch the draft versions.
            pages = pages.select_related('publisher_public__node')
        pages = get_visible_nodes(request, pages, site)

        if not pages:
            return []

        try:
            homepage = [page for page in pages if page.is_home][0]
        except IndexError:
            homepage = None

        titles = Title.objects.filter(
            language__in=languages,
            publisher_is_draft=self.renderer.draft_mode_active,
        )

        lookup = Prefetch(
            'title_set',
            to_attr='filtered_translations',
            queryset=titles,
        )
        prefetch_related_objects(pages, lookup)
        # Build the blank title instances only once
        blank_title_cache = {
            language: EmptyTitle(language=language)
            for language in languages
        }

        if lang not in blank_title_cache:
            blank_title_cache[lang] = EmptyTitle(language=lang)

        # Maps a node id to its page id
        node_id_to_page = {}

        def _page_to_node(page):
            # EmptyTitle is used to prevent the cms from trying
            # to find a translation in the database
            page.title_cache = blank_title_cache.copy()

            for trans in page.filtered_translations:
                page.title_cache[trans.language] = trans
            menu_node = get_menu_node_for_page(
                self.renderer,
                page,
                language=lang,
                fallbacks=fallbacks,
            )
            return menu_node

        menu_nodes = []

        for page in pages:
            node = page.node
            parent_id = node_id_to_page.get(node.parent_id)

            if node.parent_id and not parent_id:
                # If the parent page is not available (unpublished, etc..)
                # don't bother creating menu nodes for its descendants.
                continue

            menu_node = _page_to_node(page)
            cut_homepage = homepage and not homepage.in_navigation

            if cut_homepage and parent_id == homepage.pk:
                # When the homepage is hidden from navigation,
                # we need to cut all its direct children from it.
                menu_node.parent_id = None
            else:
                menu_node.parent_id = parent_id
            node_id_to_page[node.pk] = page.pk
            menu_nodes.append(menu_node)
        return menu_nodes
Beispiel #41
0
def details(request, slug):
    """
    The main view of the Django-CMS! Takes a request and a slug, renders the
    page.
    """
    response_timestamp = now()
    if get_cms_setting("PAGE_CACHE") and (
            not hasattr(request, 'toolbar') or
        (not request.toolbar.edit_mode_active
         and not request.toolbar.show_toolbar
         and not request.user.is_authenticated())):
        cache_content = get_page_cache(request)
        if cache_content is not None:
            content, headers, expires_datetime = cache_content
            response = HttpResponse(content)
            response._headers = headers
            # Recalculate the max-age header for this cached response
            max_age = int((expires_datetime -
                           response_timestamp).total_seconds() + 0.5)
            patch_cache_control(response, max_age=max_age)
            return response

    # Get a Page model object from the request
    site = get_current_site()
    page = get_page_from_request(request, use_path=slug)
    toolbar = get_toolbar_from_request(request)
    tree_nodes = TreeNode.objects.get_for_site(site)

    if not page and not slug and not tree_nodes.exists():
        # render the welcome page if the requested path is root "/"
        # and there's no pages
        return _render_welcome_page(request)

    if not page:
        # raise 404
        _handle_no_page(request)

    request.current_page = page

    if hasattr(request, 'user') and request.user.is_staff:
        user_languages = get_language_list(site_id=site.pk)
    else:
        user_languages = get_public_languages(site_id=site.pk)

    request_language = get_language_from_request(request, check_path=True)

    if not page.is_home and request_language not in user_languages:
        # The homepage is treated differently because
        # when a request goes to the root of the site (/)
        # without a language, Django will redirect to the user's
        # browser language which might not be a valid cms language,
        # this means we need to correctly redirect that request.
        return _handle_no_page(request)

    # get_published_languages will return all languages in draft mode
    # and published only in live mode.
    # These languages are then filtered out by the user allowed languages
    available_languages = [
        language for language in user_languages
        if language in list(page.get_published_languages())
    ]

    own_urls = [
        request.build_absolute_uri(request.path),
        '/%s' % request.path,
        request.path,
    ]

    try:
        redirect_on_fallback = get_redirect_on_fallback(request_language,
                                                        site_id=site.pk)
    except LanguageError:
        redirect_on_fallback = False

    if request_language not in user_languages:
        # Language is not allowed
        # Use the default site language
        default_language = get_default_language_for_site(site.pk)
        fallbacks = get_fallback_languages(default_language, site_id=site.pk)
        fallbacks = [default_language] + fallbacks
    else:
        fallbacks = get_fallback_languages(request_language, site_id=site.pk)

    # Only fallback to languages the user is allowed to see
    fallback_languages = [
        language for language in fallbacks
        if language != request_language and language in available_languages
    ]
    language_is_unavailable = request_language not in available_languages

    if language_is_unavailable and not fallback_languages:
        # There is no page with the requested language
        # and there's no configured fallbacks
        return _handle_no_page(request)
    elif language_is_unavailable and (redirect_on_fallback or page.is_home):
        # There is no page with the requested language and
        # the user has explicitly requested to redirect on fallbacks,
        # so redirect to the first configured / available fallback language
        fallback = fallback_languages[0]
        redirect_url = page.get_absolute_url(fallback, fallback=False)
    else:
        page_path = page.get_absolute_url(request_language)
        page_slug = page.get_path(request_language) or page.get_slug(
            request_language)

        if slug and slug != page_slug and request.path[:len(page_path
                                                            )] != page_path:
            # The current language does not match its slug.
            # Redirect to the current language.
            return HttpResponseRedirect(page_path)
        # Check if the page has a redirect url defined for this language.
        redirect_url = page.get_redirect(request_language,
                                         fallback=False) or ''
        redirect_url = _clean_redirect_url(redirect_url, request_language)

    if redirect_url:
        if request.user.is_staff and toolbar.edit_mode_active:
            toolbar.redirect_url = redirect_url
        elif redirect_url not in own_urls:
            # prevent redirect to self
            return HttpResponseRedirect(redirect_url)

    # permission checks
    if page.login_required and not request.user.is_authenticated():
        return redirect_to_login(urlquote(request.get_full_path()),
                                 settings.LOGIN_URL)

    if hasattr(request, 'toolbar'):
        request.toolbar.set_object(page)

    structure_requested = get_cms_setting(
        'CMS_TOOLBAR_URL__BUILD') in request.GET

    if user_can_change_page(request.user, page) and structure_requested:
        return render_object_structure(request, page)
    return render_page(request,
                       page,
                       current_language=request_language,
                       slug=slug)
Beispiel #42
0
def details(request, slug):
    """
    The main view of the Django-CMS! Takes a request and a slug, renders the
    page.
    """
    from django.core.cache import cache

    if get_cms_setting("PAGE_CACHE") and (
            not hasattr(request, 'toolbar') or
        (not request.toolbar.edit_mode and not request.toolbar.show_toolbar
         and not request.user.is_authenticated())):
        cache_content = cache.get(_get_cache_key(request),
                                  version=_get_cache_version())
        if not cache_content is None:
            content, headers = cache_content
            response = HttpResponse(content)
            response._headers = headers
            return response

    # Get a Page model object from the request
    page = get_page_from_request(request, use_path=slug)
    if not page:
        return _handle_no_page(request, slug)
    current_language = request.REQUEST.get('language', None)
    if current_language:
        current_language = get_language_code(current_language)
        if not current_language in get_language_list(page.site_id):
            current_language = None
    if current_language is None:
        current_language = get_language_code(
            getattr(request, 'LANGUAGE_CODE', None))
        if current_language:
            current_language = get_language_code(current_language)
            if not current_language in get_language_list(page.site_id):
                current_language = None
    if current_language is None:
        current_language = get_language_code(get_language())
    # Check that the current page is available in the desired (current) language
    available_languages = []
    page_languages = list(page.get_languages())
    if hasattr(request, 'user') and request.user.is_staff:
        user_languages = get_language_list()
    else:
        user_languages = get_public_languages()
    for frontend_lang in user_languages:
        if frontend_lang in page_languages:
            available_languages.append(frontend_lang)
    # Check that the language is in FRONTEND_LANGUAGES:
    own_urls = [
        'http%s://%s%s' %
        ('s' if request.is_secure() else '', request.get_host(), request.path),
        '/%s' % request.path,
        request.path,
    ]
    if not current_language in user_languages:
        #are we on root?
        if not slug:
            #redirect to supported language
            languages = []
            for language in available_languages:
                languages.append((language, language))
            if languages:
                with SettingsOverride(LANGUAGES=languages,
                                      LANGUAGE_CODE=languages[0][0]):
                    #get supported language
                    new_language = get_language_from_request(request)
                    if new_language in get_public_languages():
                        with force_language(new_language):
                            pages_root = reverse('pages-root')
                            if hasattr(
                                    request, 'toolbar'
                            ) and request.user.is_staff and request.toolbar.edit_mode:
                                request.toolbar.redirect_url = pages_root
                            elif pages_root not in own_urls:
                                return HttpResponseRedirect(pages_root)
            elif not hasattr(request,
                             'toolbar') or not request.toolbar.redirect_url:
                _handle_no_page(request, slug)
        else:
            return _handle_no_page(request, slug)
    if current_language not in available_languages:
        # If we didn't find the required page in the requested (current)
        # language, let's try to find a fallback
        found = False
        for alt_lang in get_fallback_languages(current_language):
            if alt_lang in available_languages:
                if get_redirect_on_fallback(current_language) or slug == "":
                    with force_language(alt_lang):
                        path = page.get_absolute_url(language=alt_lang,
                                                     fallback=True)
                        # In the case where the page is not available in the
                    # preferred language, *redirect* to the fallback page. This
                    # is a design decision (instead of rendering in place)).
                    if hasattr(
                            request, 'toolbar'
                    ) and request.user.is_staff and request.toolbar.edit_mode:
                        request.toolbar.redirect_url = path
                    elif path not in own_urls:
                        return HttpResponseRedirect(path)
                else:
                    found = True
        if not found and (not hasattr(request, 'toolbar')
                          or not request.toolbar.redirect_url):
            # There is a page object we can't find a proper language to render it
            _handle_no_page(request, slug)

    if apphook_pool.get_apphooks():
        # There are apphooks in the pool. Let's see if there is one for the
        # current page
        # since we always have a page at this point, applications_page_check is
        # pointless
        # page = applications_page_check(request, page, slug)
        # Check for apphooks! This time for real!
        app_urls = page.get_application_urls(current_language, False)
        skip_app = False
        if not page.is_published(current_language) and hasattr(
                request, 'toolbar') and request.toolbar.edit_mode:
            skip_app = True
        if app_urls and not skip_app:
            app = apphook_pool.get_apphook(app_urls)
            pattern_list = []
            for urlpatterns in get_app_urls(app.urls):
                pattern_list += urlpatterns
            urlpatterns = patterns('', *pattern_list)
            try:
                view, args, kwargs = resolve('/', tuple(urlpatterns))
                return view(request, *args, **kwargs)
            except Resolver404:
                pass
                # Check if the page has a redirect url defined for this language.
    redirect_url = page.get_redirect(language=current_language)
    if redirect_url:
        if (is_language_prefix_patterns_used() and redirect_url[0] == "/"
                and not redirect_url.startswith('/%s/' % current_language)):
            # add language prefix to url
            redirect_url = "/%s/%s" % (current_language,
                                       redirect_url.lstrip("/"))
            # prevent redirect to self

        if hasattr(request, 'toolbar'
                   ) and request.user.is_staff and request.toolbar.edit_mode:
            request.toolbar.redirect_url = redirect_url
        elif redirect_url not in own_urls:
            return HttpResponseRedirect(redirect_url)

    # permission checks
    if page.login_required and not request.user.is_authenticated():
        return redirect_to_login(urlquote(request.get_full_path()),
                                 settings.LOGIN_URL)
    if hasattr(request, 'toolbar'):
        request.toolbar.set_object(page)

    template_name = get_template_from_request(request,
                                              page,
                                              no_current_page=True)
    # fill the context
    context = RequestContext(request)
    context['lang'] = current_language
    context['current_page'] = page
    context['has_change_permissions'] = page.has_change_permission(request)
    context['has_view_permissions'] = page.has_view_permission(request)

    if not context['has_view_permissions']:
        return _handle_no_page(request, slug)

    response = TemplateResponse(request, template_name, context)

    response.add_post_render_callback(_cache_page)

    # Add headers for X Frame Options - this really should be changed upon moving to class based views
    xframe_options = page.get_xframe_options()
    if xframe_options == Page.X_FRAME_OPTIONS_INHERIT:
        # This is when we defer to django's own clickjacking handling
        return response

    # We want to prevent django setting this in their middlewear
    response.xframe_options_exempt = True

    if xframe_options == Page.X_FRAME_OPTIONS_ALLOW:
        # Do nothing, allowed is no header.
        return response
    elif xframe_options == Page.X_FRAME_OPTIONS_SAMEORIGIN:
        response['X-Frame-Options'] = 'SAMEORIGIN'
    elif xframe_options == Page.X_FRAME_OPTIONS_DENY:
        response['X-Frame-Options'] = 'DENY'

    return response
def article(request, slug):
    """
    The main view of the Django-CMS Articles! Takes a request and a slug,
    renders the article.
    """
    # Get current CMS Page as article tree
    tree = request.current_page

    # Check whether it really is a tree.
    # It could also be one of its sub-pages.
    if tree.application_urls != 'CMSArticlesApp':
        # In such case show regular CMS Page
        return page(request, slug)

    # Get an Article object from the request
    draft = use_draft(request) and request.user.has_perm(
        'cms_articles.change_article')
    preview = 'preview' in request.GET and request.user.has_perm(
        'cms_articles.change_article')

    site = tree.node.site
    article = get_article_from_slug(tree, slug, preview, draft)

    if not article:
        # raise 404
        _handle_no_page(request)

    request.current_article = article

    if hasattr(request, 'user') and request.user.is_staff:
        user_languages = get_language_list(site_id=site.pk)
    else:
        user_languages = get_public_languages(site_id=site.pk)

    request_language = get_language_from_request(request, check_path=True)

    # get_published_languages will return all languages in draft mode
    # and published only in live mode.
    # These languages are then filtered out by the user allowed languages
    available_languages = [
        language for language in user_languages
        if language in list(article.get_published_languages())
    ]

    own_urls = [
        request.build_absolute_uri(request.path),
        '/%s' % request.path,
        request.path,
    ]

    try:
        redirect_on_fallback = get_redirect_on_fallback(request_language,
                                                        site_id=site.pk)
    except LanguageError:
        redirect_on_fallback = False

    if request_language not in user_languages:
        # Language is not allowed
        # Use the default site language
        default_language = get_default_language_for_site(site.pk)
        fallbacks = get_fallback_languages(default_language, site_id=site.pk)
        fallbacks = [default_language] + fallbacks
    else:
        fallbacks = get_fallback_languages(request_language, site_id=site.pk)

    # Only fallback to languages the user is allowed to see
    fallback_languages = [
        language for language in fallbacks
        if language != request_language and language in available_languages
    ]
    language_is_unavailable = request_language not in available_languages

    if language_is_unavailable and not fallback_languages:
        # There is no page with the requested language
        # and there's no configured fallbacks
        return _handle_no_page(request)
    elif language_is_unavailable and redirect_on_fallback:
        # There is no page with the requested language and
        # the user has explicitly requested to redirect on fallbacks,
        # so redirect to the first configured / available fallback language
        fallback = fallback_languages[0]
        redirect_url = article.get_absolute_url(fallback, fallback=False)
    else:
        redirect_url = False

    if redirect_url:
        if request.user.is_staff and hasattr(
                request, 'toolbar') and request.toolbar.edit_mode_active:
            request.toolbar.redirect_url = redirect_url
        elif redirect_url not in own_urls:
            # prevent redirect to self
            return HttpResponseRedirect(redirect_url)

    # permission checks
    if article.login_required and not request.user.is_authenticated():
        return redirect_to_login(urlquote(request.get_full_path()),
                                 settings.LOGIN_URL)

    if hasattr(request, 'toolbar'):
        request.toolbar.obj = article

    structure_requested = get_cms_setting(
        'CMS_TOOLBAR_URL__BUILD') in request.GET

    if article.has_change_permission(request) and structure_requested:
        return render_object_structure(request, article)
    return render_article(request,
                          article,
                          current_language=request_language,
                          slug=slug)
Beispiel #44
0
 def test_get_fallback_languages(self):
     languages = i18n.get_fallback_languages('en', 1)
     self.assertEqual(languages, ['de', 'fr'])
Beispiel #45
0
 def test_get_fallback_languages(self):
     languages = i18n.get_fallback_languages('en', 1)
     self.assertEqual(languages, ['de', 'fr'])
Beispiel #46
0
def show_menu(context, from_level=0, to_level=100, extra_inactive=0, extra_active=100, template="cms/menu.html", next_page=None, root_id=None):
    """
    render a nested list of all children of the pages
    from_level: is the start level
    to_level: is the max level rendered
    render_children: if set to True will render all not direct ascendants too
    """
    try:
        # If there's an exception (500), default context_processors may not be called.
        request = context['request']
    except KeyError:
        return {'template': 'cms/empty.html'}
    page_queryset = get_page_queryset(request)
    site = Site.objects.get_current()
    lang = get_language_from_request(request)
    current_page = request.current_page
    if current_page == "dummy":
        context.update({'children':[],
                    'template':template,
                    'from_level':from_level,
                    'to_level':to_level,
                    'extra_inactive':extra_inactive,
                    'extra_active':extra_active})
        return context
    if hasattr(current_page, "home_pk_cache"):
        home_pk = current_page.home_pk_cache
    else:
        try:
            home_pk = page_queryset.get_home(site).pk
        except NoHomeFound:
            home_pk = 0
    if not next_page: #new menu... get all the data so we can save a lot of queries
        
        children = []
        ancestors = []
        if current_page:
            alist = current_page.get_ancestors().values_list('id', 'soft_root')
        else:# maybe the active node is in an extender?
            alist = []
            extenders = page_queryset.published().filter(in_navigation=True, 
                                                        site=site, 
                                                        level__lte=to_level)
            extenders = extenders.exclude(navigation_extenders__isnull=True).exclude( navigation_extenders__exact="")
            for ext in extenders:
                ext.childrens = []
                ext.ancestors_ascending = []
                get_extended_navigation_nodes(request, 100, [ext], ext.level, 100, 100, False, ext.navigation_extenders)
                if hasattr(ext, "ancestor"):
                    alist = list(ext.get_ancestors().values_list('id', 'soft_root'))
                    alist = [(ext.pk, ext.soft_root)] + alist
                    break
        filters = {'in_navigation' : True, 
                   'site' : site,
                   'level__lte' : to_level}
        #check the ancestors for softroots
        soft_root_pk = None
        for p in alist:
            ancestors.append(p[0])
            if p[1]:
                soft_root_pk = p[0]
        #modify filters if we don't start from the root
        root_page = None
        if root_id:
            try:
                root_page = page_queryset.get(reverse_id=root_id, site=site)
            except:
                send_missing_mail(root_id, request)
        else:
            if current_page and current_page.soft_root:
                root_page = current_page
                soft_root_pk = current_page.pk
            elif soft_root_pk:
                root_page = page_queryset.get(pk=soft_root_pk)
        if root_page:
            if isinstance(root_page, int):
                root_page = page_queryset.get(pk=root_page)
            if isinstance(root_page, Page):
                root_page = page_queryset.get(pk=root_page.id)
            elif isinstance(root_page, unicode):
                root_page = page_queryset.get(reverse_id=root_page, site=site)
            filters['tree_id'] = root_page.tree_id
            filters['lft__gt'] = root_page.lft
            filters['rght__lt'] = root_page.rght
            filters['level__lte'] = root_page.level + to_level
            db_from_level = root_page.level + from_level
        else:
            db_from_level = from_level
        if settings.CMS_HIDE_UNTRANSLATED:
            filters['title_set__language'] = lang
        if not request.user.is_authenticated():
            filters['menu_login_required'] = False
        pages = page_queryset.published().filter(**filters).order_by('tree_id', 
                                                                    'parent', 
                                                                    'lft')
        pages = list(pages)
        if root_page:
            pages = [root_page] + pages
        all_pages = pages[:]
        root_level = getattr(root_page, 'level', None)
        ids = []
        for page in pages:# build the tree
            if page.level >= db_from_level:
                ids.append(page.pk)
            if page.level == 0 or page.level == root_level:
                if page.parent_id:
                    page.get_cached_ancestors()
                else:
                    page.ancestors_ascending = []
                page.home_pk_cache = home_pk
                page.menu_level = 0 - from_level
                page.childrens = []
                children.append(page)
                if page.pk == soft_root_pk:
                    page.soft_root = False #ugly hack for the recursive function
                if current_page:
                    pk = current_page.pk
                else:
                    pk = -1
                find_children(page, pages, extra_inactive, extra_active, ancestors, pk, request=request, to_levels=to_level)
                if page.pk == soft_root_pk:
                    page.soft_root = True
        if db_from_level > 0:
            children = cut_levels(children, db_from_level)
        titles = list(get_title_queryset(request).filter(page__in=ids, language=lang))
        for page in all_pages:# add the title and slugs and some meta data
            for title in titles:
                if title.page_id == page.pk:
                    if not hasattr(page, "title_cache"):
                        page.title_cache = {}
                    page.title_cache[title.language] = title
                    ids.remove(page.pk)
            if page.pk in ancestors:
                page.ancestor = True
            if current_page and page.parent_id == current_page.parent_id and not page.pk == current_page.pk:
                page.sibling = True
        if ids:
            fallbacks = get_fallback_languages(lang)
            for l in fallbacks:
                titles = list(get_title_queryset(request).filter(page__in=ids, language=l))
                for page in all_pages:# add the title and slugs and some meta data
                    for title in titles:
                        if title.page_id == page.pk:
                            if not hasattr(page, "title_cache"):
                                page.title_cache = {}
                            page.title_cache[title.language] = title
                            ids.remove(page.pk)
                if not ids:
                    break
        children = navigation.handle_navigation_manipulators(children, request)
    else:
        children = next_page.childrens
    context.update({'children':children,
                    'template':template,
                    'from_level':from_level,
                    'to_level':to_level,
                    'extra_inactive':extra_inactive,
                    'extra_active':extra_active})
    return context
def details(request, slug):
    """
    The main view of the Django-CMS! Takes a request and a slug, renders the
    page.
    """
    from django.core.cache import cache

    if get_cms_setting("PAGE_CACHE") and (
        not hasattr(request, 'toolbar') or (
            not request.toolbar.edit_mode and
            not request.toolbar.show_toolbar and
            not request.user.is_authenticated()
        )
    ):
        cache_content = cache.get(
            _get_cache_key(request),
            version=_get_cache_version()
        )
        if not cache_content is None:
            content, headers = cache_content
            response = HttpResponse(content)
            response._headers = headers
            return response

    # Get a Page model object from the request
    page = get_page_from_request(request, use_path=slug)
    if not page:
        return _handle_no_page(request, slug)
    current_language = request.REQUEST.get('language', None)
    if current_language:
        current_language = get_language_code(current_language)
        if not current_language in get_language_list(page.site_id):
            current_language = None
    if current_language is None:
        current_language = get_language_code(getattr(request, 'LANGUAGE_CODE', None))
        if current_language:
            current_language = get_language_code(current_language)
            if not current_language in get_language_list(page.site_id):
                current_language = None
    if current_language is None:
        current_language = get_language_code(get_language())
    # Check that the current page is available in the desired (current) language
    available_languages = []
    page_languages = list(page.get_languages())
    if hasattr(request, 'user') and request.user.is_staff:
        user_languages = get_language_list()
    else:
        user_languages = get_public_languages()
    for frontend_lang in user_languages:
        if frontend_lang in page_languages:
            available_languages.append(frontend_lang)
    # Check that the language is in FRONTEND_LANGUAGES:
    own_urls = [
        'http%s://%s%s' % ('s' if request.is_secure() else '', request.get_host(), request.path),
        '/%s' % request.path,
        request.path,
    ]
    if not current_language in user_languages:
        #are we on root?
        if not slug:
            #redirect to supported language
            languages = []
            for language in available_languages:
                languages.append((language, language))
            if languages:
                with SettingsOverride(LANGUAGES=languages, LANGUAGE_CODE=languages[0][0]):
                    #get supported language
                    new_language = get_language_from_request(request)
                    if new_language in get_public_languages():
                        with force_language(new_language):
                            pages_root = reverse('pages-root')
                            if hasattr(request, 'toolbar') and request.user.is_staff and request.toolbar.edit_mode:
                                request.toolbar.redirect_url = pages_root
                            elif pages_root not in own_urls:
                                return HttpResponseRedirect(pages_root)
            elif not hasattr(request, 'toolbar') or not request.toolbar.redirect_url:
                _handle_no_page(request, slug)
        else:
            return _handle_no_page(request, slug)
    if current_language not in available_languages:
        # If we didn't find the required page in the requested (current)
        # language, let's try to find a fallback
        found = False
        for alt_lang in get_fallback_languages(current_language):
            if alt_lang in available_languages:
                if get_redirect_on_fallback(current_language) or slug == "":
                    with force_language(alt_lang):
                        path = page.get_absolute_url(language=alt_lang, fallback=True)
                        # In the case where the page is not available in the
                    # preferred language, *redirect* to the fallback page. This
                    # is a design decision (instead of rendering in place)).
                    if hasattr(request, 'toolbar') and request.user.is_staff and request.toolbar.edit_mode:
                        request.toolbar.redirect_url = path
                    elif path not in own_urls:
                        return HttpResponseRedirect(path)
                else:
                    found = True
        if not found and (not hasattr(request, 'toolbar') or not request.toolbar.redirect_url):
            # There is a page object we can't find a proper language to render it
            _handle_no_page(request, slug)

    if apphook_pool.get_apphooks():
        # There are apphooks in the pool. Let's see if there is one for the
        # current page
        # since we always have a page at this point, applications_page_check is
        # pointless
        # page = applications_page_check(request, page, slug)
        # Check for apphooks! This time for real!
        app_urls = page.get_application_urls(current_language, False)
        skip_app = False
        if not page.is_published(current_language) and hasattr(request, 'toolbar') and request.toolbar.edit_mode:
            skip_app = True
        if app_urls and not skip_app:
            app = apphook_pool.get_apphook(app_urls)
            pattern_list = []
            for urlpatterns in get_app_urls(app.urls):
                pattern_list += urlpatterns
            urlpatterns = patterns('', *pattern_list)
            try:
                view, args, kwargs = resolve('/', tuple(urlpatterns))
                return view(request, *args, **kwargs)
            except Resolver404:
                pass
                # Check if the page has a redirect url defined for this language.
    redirect_url = page.get_redirect(language=current_language)
    if redirect_url:
        if (is_language_prefix_patterns_used() and redirect_url[0] == "/" and not redirect_url.startswith(
                    '/%s/' % current_language)):
            # add language prefix to url
            redirect_url = "/%s/%s" % (current_language, redirect_url.lstrip("/"))
            # prevent redirect to self

        if hasattr(request, 'toolbar') and request.user.is_staff and request.toolbar.edit_mode:
            request.toolbar.redirect_url = redirect_url
        elif redirect_url not in own_urls:
            return HttpResponseRedirect(redirect_url)

    # permission checks
    if page.login_required and not request.user.is_authenticated():
        return redirect_to_login(urlquote(request.get_full_path()), settings.LOGIN_URL)
    if hasattr(request, 'toolbar'):
        request.toolbar.set_object(page)

    template_name = get_template_from_request(request, page, no_current_page=True)
    # fill the context
    context = RequestContext(request)
    context['lang'] = current_language
    context['current_page'] = page
    context['has_change_permissions'] = page.has_change_permission(request)
    context['has_view_permissions'] = page.has_view_permission(request)

    if not context['has_view_permissions']:
        return _handle_no_page(request, slug)

    response = TemplateResponse(request, template_name, context)

    response.add_post_render_callback(_cache_page)

    # Add headers for X Frame Options - this really should be changed upon moving to class based views
    xframe_options = page.get_xframe_options()
    if xframe_options == Page.X_FRAME_OPTIONS_INHERIT:
        # This is when we defer to django's own clickjacking handling
        return response

    # We want to prevent django setting this in their middlewear
    response.xframe_options_exempt = True

    if xframe_options == Page.X_FRAME_OPTIONS_ALLOW:
        # Do nothing, allowed is no header.
        return response
    elif xframe_options == Page.X_FRAME_OPTIONS_SAMEORIGIN:
        response['X-Frame-Options'] = 'SAMEORIGIN'
    elif xframe_options == Page.X_FRAME_OPTIONS_DENY:
        response['X-Frame-Options'] = 'DENY'

    return response
Beispiel #48
0
def details(request, slug):
    """
    The main view of the Django-CMS! Takes a request and a slug, renders the
    page.
    """
    # get the right model
    context = RequestContext(request)
    # Get a Page model object from the request
    page = get_page_from_request(request, use_path=slug)
    if not page:
        return _handle_no_page(request, slug)

    current_language = get_language_from_request(request)

    # Check that the current page is available in the desired (current) language
    available_languages = page.get_languages()

    # We resolve an alternate language for the page if it's not available.
    # Since the "old" details view had an exception for the root page, it is
    # ported here. So no resolution if the slug is ''.
    if (current_language not in available_languages):
        if settings.CMS_LANGUAGE_FALLBACK:
            # If we didn't find the required page in the requested (current)
            # language, let's try to find a suitable fallback in the list of
            # fallback languages (CMS_LANGUAGE_CONF)
            for alt_lang in get_fallback_languages(current_language):
                if alt_lang in available_languages:
                    alt_url = page.get_absolute_url(language=alt_lang,
                                                    fallback=True)
                    path = '/%s%s' % (alt_lang, alt_url)
                    # In the case where the page is not available in the
                    # preferred language, *redirect* to the fallback page. This
                    # is a design decision (instead of rendering in place)).
                    return HttpResponseRedirect(path)
        # There is a page object we can't find a proper language to render it
        _handle_no_page(request, slug)

    if apphook_pool.get_apphooks():
        # There are apphooks in the pool. Let's see if there is one for the
        # current page
        # since we always have a page at this point, applications_page_check is
        # pointless
        # page = applications_page_check(request, page, slug)
        # Check for apphooks! This time for real!
        app_urls = page.get_application_urls(current_language, False)
        if app_urls:
            app = apphook_pool.get_apphook(app_urls)
            pattern_list = []
            for urlpatterns in get_app_urls(app.urls):
                pattern_list += urlpatterns
            urlpatterns = patterns('', *pattern_list)
            try:
                view, args, kwargs = resolve('/', tuple(urlpatterns))
                return view(request, *args, **kwargs)
            except Resolver404:
                pass

    # Check if the page has a redirect url defined for this language.
    redirect_url = page.get_redirect(language=current_language)
    if redirect_url:
        if (settings.i18n_installed and redirect_url[0] == "/"
                and not redirect_url.startswith('/%s/' % current_language)):
            redirect_url = "/%s/%s" % (current_language,
                                       redirect_url.lstrip("/"))
        # add language prefix to url
        return HttpResponseRedirect(redirect_url)

    # permission checks
    if page.login_required and not request.user.is_authenticated():
        if settings.i18n_installed:
            path = urlquote("/%s%s" %
                            (request.LANGUAGE_CODE, request.get_full_path()))
        else:
            path = urlquote(request.get_full_path())
        tup = settings.LOGIN_URL, "next", path
        return HttpResponseRedirect('%s?%s=%s' % tup)

    template_name = get_template_from_request(request,
                                              page,
                                              no_current_page=True)
    # fill the context
    context['lang'] = current_language
    context['current_page'] = page
    context['has_change_permissions'] = page.has_change_permission(request)
    context['has_view_permissions'] = page.has_view_permission(request)

    if not context['has_view_permissions']:
        return _handle_no_page(request, slug)

    return render_to_response(template_name, context)
Beispiel #49
0
def has_fallback_language(language):
    try:
        language_list = get_fallback_languages(language)
        return len(language_list) > 0
    except:
        return False
Beispiel #50
0
def details(request, slug):
    """
    The main view of the Django-CMS! Takes a request and a slug, renders the
    page.
    """
    from cms.apphook_pool import apphook_pool
    from cms.appresolver import get_app_urls
    from cms.utils import get_template_from_request, get_language_from_request
    from cms.utils.i18n import get_fallback_languages
    from cms.utils.django_load import load_object
    from cms.utils.page_resolver import get_page_from_request
    from cms.views import _handle_no_page
    from django.conf import settings
    from django.conf.urls import patterns
    from django.core.urlresolvers import resolve, Resolver404

    from django.http import Http404, HttpResponseRedirect
    from django.shortcuts import render_to_response
    from django.template.context import RequestContext
    from django.utils.http import urlquote
    # get the right model
    context = RequestContext(request)
    # Get a Page model object from the request
    page = get_page_from_request(request, use_path=slug)
    if not page:
        return _handle_no_page(request, slug)

    current_language = get_language_from_request(request)

    # Check that the current page is available in the desired (current) language
    available_languages = page.get_languages()

    # We resolve an alternate language for the page if it's not available.
    # Since the "old" details view had an exception for the root page, it is
    # ported here. So no resolution if the slug is ''.
    if (current_language not in available_languages):
        if settings.CMS_LANGUAGE_FALLBACK:
            # If we didn't find the required page in the requested (current)
            # language, let's try to find a suitable fallback in the list of
            # fallback languages (CMS_LANGUAGE_CONF)
            for alt_lang in get_fallback_languages(current_language):
                if alt_lang in available_languages:
                    alt_url = page.get_absolute_url(language=alt_lang, fallback=True)
                    path = '/%s%s' % (alt_lang, alt_url)
                    # In the case where the page is not available in the
                    # preferred language, *redirect* to the fallback page. This
                    # is a design decision (instead of rendering in place)).
                    return HttpResponseRedirect(path)
            # There is a page object we can't find a proper language to render it
        _handle_no_page(request, slug)

    if apphook_pool.get_apphooks():
        # There are apphooks in the pool. Let's see if there is one for the
        # current page
        # since we always have a page at this point, applications_page_check is
        # pointless
        # page = applications_page_check(request, page, slug)
        # Check for apphooks! This time for real!
        app_urls = page.get_application_urls(current_language, False)
        if app_urls:
            app = apphook_pool.get_apphook(app_urls)
            pattern_list = []
            for urlpatterns in get_app_urls(app.urls):
                pattern_list += urlpatterns
            urlpatterns = patterns('', *pattern_list)
            try:
                view, args, kwargs = resolve('/', tuple(urlpatterns))
                return view(request, *args, **kwargs)
            except Resolver404:
                pass

    if page.view_path:
        view = load_object(page.view_path)
        args, kwargs = view.extract_args_kwargs(slug)
        return view(request, *args, **kwargs)

    # Check if the page has a redirect url defined for this language.
    redirect_url = page.get_redirect(language=current_language)
    if redirect_url:
        if (settings.i18n_installed and redirect_url[0] == "/"
            and not redirect_url.startswith('/%s/' % current_language)):
            # add language prefix to url
            redirect_url = "/%s/%s" % (current_language, redirect_url.lstrip("/"))
            # prevent redirect to self
        own_urls = [
            'http%s://%s%s' % ('s' if request.is_secure() else '', request.get_host(), request.path),
            '/%s%s' % (current_language, request.path),
            request.path,
            ]
        if redirect_url not in own_urls:
            return HttpResponseRedirect(redirect_url)

    # permission checks
    if page.login_required and not request.user.is_authenticated():
        if settings.i18n_installed:
            path = urlquote("/%s%s" % (request.LANGUAGE_CODE, request.get_full_path()))
        else:
            path = urlquote(request.get_full_path())
        tup = settings.LOGIN_URL , "next", path
        return HttpResponseRedirect('%s?%s=%s' % tup)

    template_name = get_template_from_request(request, page, no_current_page=True)
    # fill the context
    context['lang'] = current_language
    context['current_page'] = page
    context['has_change_permissions'] = page.has_change_permission(request)
    context['has_view_permissions'] = page.has_view_permission(request)

    if not context['has_view_permissions']:
        return _handle_no_page(request, slug)

    return render_to_response(template_name, context)
Beispiel #51
0
    def get_nodes(self, request):
        page_queryset = get_page_queryset(request)
        site = Site.objects.get_current()
        lang = get_language_from_request(request)
        
        filters = {
            'site':site,
        }
        
        if settings.CMS_HIDE_UNTRANSLATED:
            filters['title_set__language'] = lang
            
        pages = page_queryset.published().filter(**filters).order_by("tree_id", "lft")
        
        ids = []
        nodes = []
        first = True
        home_cut = False
        home_children = []
        home = None
        actual_pages = []
        
        # cache view perms
        visible_pages = get_visible_pages(request, pages, site)
        for page in pages:
            # Pages are ordered by tree_id, therefore the first page is the root
            # of the page tree (a.k.a "home")
            if page.pk not in visible_pages:
                # Don't include pages the user doesn't have access to
                continue
            if not home:
                home = page
            page.home_pk_cache = home.pk
            if first and page.pk != home.pk:
                home_cut = True
            if (page.parent_id == home.pk or page.parent_id in home_children) and home_cut:
                home_children.append(page.pk)
            if (page.pk == home.pk and home.in_navigation) or page.pk != home.pk:
                first = False
            ids.append(page.id)
            actual_pages.append(page)

        titles = list(get_title_queryset(request).filter(page__in=ids, language=lang))
        for page in actual_pages: # add the title and slugs and some meta data
            for title in titles:
                if title.page_id == page.pk:
                    if not hasattr(page, "title_cache"):
                        page.title_cache = {}
                    page.title_cache[title.language] = title
                    nodes.append(page_to_node(page, home, home_cut))
                    ids.remove(page.pk)

        if ids: # get fallback languages
            fallbacks = get_fallback_languages(lang)
            for lang in fallbacks:
                titles = list(get_title_queryset(request).filter(page__in=ids, language=lang))
                for title in titles:
                    for page in actual_pages: # add the title and slugs and some meta data
                        if title.page_id == page.pk:
                            if not hasattr(page, "title_cache"):
                                page.title_cache = {}
                            page.title_cache[title.language] = title
                            nodes.append(page_to_node(page, home, home_cut))
                            ids.remove(page.pk)
                            break
                if not ids:
                    break
        return nodes  
def render_placeholder(placeholder,
                       context_to_copy,
                       name_fallback="Placeholder",
                       lang=None):
    """
    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']
    page = placeholder.page if placeholder else None
    if page:
        template = page.template
    else:
        template = 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 not lang:
        lang = get_language_from_request(request)
    plugins = [
        plugin for plugin in get_plugins(request, placeholder, lang=lang)
    ]
    # If no plugin is present in the current placeholder we loop in the fallback languages
    # and get the first available set of plugins
    if (len(plugins) == 0 and placeholder and get_placeholder_conf(
            "language_fallback", placeholder.slot, template, False)):
        fallbacks = get_fallback_languages(lang)
        for fallback_language in fallbacks:
            plugins = [
                plugin for plugin in get_plugins(request, placeholder,
                                                 fallback_language)
            ]
            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))
    toolbar_content = ''
    draggable_content = ''
    if edit:
        toolbar_content = mark_safe(
            render_placeholder_toolbar(placeholder,
                                       context,
                                       '',
                                       name_fallback=name_fallback))
        draggable_content = mark_safe(render_dragables(plugins, slot, request))
    content = mark_safe("".join(content))

    result = render_to_string(
        "cms/toolbar/placeholder.html", {
            'plugins': content,
            "bar": toolbar_content,
            "draggables": draggable_content,
            'edit': edit
        })
    context.pop()
    return result
Beispiel #53
0
def details(request, slug):
    """
    The main view of the Django-CMS! Takes a request and a slug, renders the
    page.
    """
    # get the right model
    context = RequestContext(request)
    # Get a Page model object from the request
    page = get_page_from_request(request, use_path=slug)
    if not page:
        return _handle_no_page(request, slug)

    current_language = get_language_from_request(request)
    # Check that the current page is available in the desired (current) language
    available_languages = []
    page_languages = page.get_languages()
    user_languages = get_public_languages()
    if hasattr(request, 'user') and request.user.is_staff:
        user_languages = get_language_list()
    for frontend_lang in user_languages:
        if frontend_lang in page_languages:
            available_languages.append(frontend_lang)
    attrs = ''
    if 'edit' in request.GET:
        attrs = '?edit=1'
    elif 'preview' in request.GET:
        attrs = '?preview=1'
        if 'draft' in request.GET:
            attrs += '&draft=1'
    # Check that the language is in FRONTEND_LANGUAGES:
    if not current_language in user_languages:
        #are we on root?
        if not slug:
            #redirect to supported language
            languages = []
            for language in available_languages:
                languages.append((language, language))
            if languages:
                with SettingsOverride(LANGUAGES=languages, LANGUAGE_CODE=languages[0][0]):
                    #get supported language
                    new_language = translation.get_language_from_request(request)
                    if new_language in get_public_languages():
                        with force_language(new_language):
                            pages_root = reverse('pages-root')
                            return HttpResponseRedirect(pages_root + attrs)
            else:
                _handle_no_page(request, slug)
        else:
            return _handle_no_page(request, slug)
    if current_language not in available_languages:
        # If we didn't find the required page in the requested (current)
        # language, let's try to find a fallback
        found = False
        for alt_lang in get_fallback_languages(current_language):
            if alt_lang in available_languages:
                if get_redirect_on_fallback(current_language):
                    with force_language(alt_lang):
                        path = page.get_absolute_url(language=alt_lang, fallback=True)
                        # In the case where the page is not available in the
                    # preferred language, *redirect* to the fallback page. This
                    # is a design decision (instead of rendering in place)).
                    return HttpResponseRedirect(path + attrs)
                else:
                    found = True
        if not found:
            # There is a page object we can't find a proper language to render it
            _handle_no_page(request, slug)

    if apphook_pool.get_apphooks():
        # There are apphooks in the pool. Let's see if there is one for the
        # current page
        # since we always have a page at this point, applications_page_check is
        # pointless
        # page = applications_page_check(request, page, slug)
        # Check for apphooks! This time for real!
        try:
            app_urls = page.get_application_urls(current_language, False)
        except Title.DoesNotExist:
            app_urls = []
        if app_urls:
            app = apphook_pool.get_apphook(app_urls)
            pattern_list = []
            for urlpatterns in get_app_urls(app.urls):
                pattern_list += urlpatterns
            urlpatterns = patterns('', *pattern_list)
            try:
                context.current_app = page.reverse_id if page.reverse_id else app.app_name
                view, args, kwargs = resolve('/', tuple(urlpatterns))
                return view(request, *args, **kwargs)
            except Resolver404:
                pass
        # Check if the page has a redirect url defined for this language.
    redirect_url = page.get_redirect(language=current_language)
    if redirect_url:
        if (settings.USE_I18N and redirect_url[0] == "/"
            and not redirect_url.startswith('/%s/' % current_language)):
            # add language prefix to url
            redirect_url = "/%s/%s" % (current_language, redirect_url.lstrip("/"))
            # prevent redirect to self
        own_urls = [
            'http%s://%s%s' % ('s' if request.is_secure() else '', request.get_host(), request.path),
            '/%s' % request.path,
            request.path,
        ]
        if redirect_url not in own_urls:
            return HttpResponseRedirect(redirect_url + attrs)

    # permission checks
    if page.login_required and not request.user.is_authenticated():
        path = urlquote(request.get_full_path())
        tup = settings.LOGIN_URL, "next", path
        return HttpResponseRedirect('%s?%s=%s' % tup)

    template_name = get_template_from_request(request, page, no_current_page=True)
    # fill the context 
    context['lang'] = current_language
    context['current_page'] = page
    context['has_change_permissions'] = page.has_change_permission(request)
    context['has_view_permissions'] = page.has_view_permission(request)

    if not context['has_view_permissions']:
        return _handle_no_page(request, slug)

    return render_to_response(template_name, context_instance=context)
def details(request, slug):
    """
    The main view of the Django-CMS! Takes a request and a slug, renders the
    page.
    """
    response_timestamp = now()
    if get_cms_setting("PAGE_CACHE") and (
            not hasattr(request, 'toolbar') or
        (not request.toolbar.edit_mode and not request.toolbar.show_toolbar
         and not request.user.is_authenticated())):
        cache_content = get_page_cache(request)
        if cache_content is not None:
            content, headers, expires_datetime = cache_content
            response = HttpResponse(content)
            response._headers = headers
            # Recalculate the max-age header for this cached response
            max_age = int((expires_datetime -
                           response_timestamp).total_seconds() + 0.5)
            patch_cache_control(response, max_age=max_age)
            return response

    # Get a Page model object from the request
    page = get_page_from_request(request, use_path=slug)
    if not page:
        return _handle_no_page(request, slug)
    current_language = request.GET.get('language', None)
    if not current_language:
        current_language = request.POST.get('language', None)
    if current_language:
        current_language = get_language_code(current_language)
        if current_language not in get_language_list(page.site_id):
            current_language = None
    if current_language is None:
        current_language = get_language_code(
            getattr(request, 'LANGUAGE_CODE', None))
        if current_language:
            current_language = get_language_code(current_language)
            if current_language not in get_language_list(page.site_id):
                current_language = None
    if current_language is None:
        current_language = get_language_code(get_language())
    # Check that the current page is available in the desired (current) language
    available_languages = []
    # this will return all languages in draft mode, and published only in live mode
    page_languages = list(page.get_published_languages())
    if hasattr(request, 'user') and request.user.is_staff:
        user_languages = get_language_list()
    else:
        user_languages = get_public_languages()
    for frontend_lang in user_languages:
        if frontend_lang in page_languages:
            available_languages.append(frontend_lang)
    # Check that the language is in FRONTEND_LANGUAGES:
    own_urls = [
        'http%s://%s%s' %
        ('s' if request.is_secure() else '', request.get_host(), request.path),
        '/%s' % request.path,
        request.path,
    ]
    if current_language not in user_languages:
        #are we on root?
        if not slug:
            #redirect to supported language
            languages = []
            for language in available_languages:
                languages.append((language, language))
            if languages:
                # get supported language
                new_language = get_language_from_request(request)
                if new_language in get_public_languages():
                    with force_language(new_language):
                        pages_root = reverse('pages-root')
                        if (hasattr(request, 'toolbar')
                                and request.user.is_staff
                                and request.toolbar.edit_mode):
                            request.toolbar.redirect_url = pages_root
                        elif pages_root not in own_urls:
                            return HttpResponseRedirect(pages_root)
            elif not hasattr(request,
                             'toolbar') or not request.toolbar.redirect_url:
                _handle_no_page(request, slug)
        else:
            return _handle_no_page(request, slug)
    if current_language not in available_languages:
        # If we didn't find the required page in the requested (current)
        # language, let's try to find a fallback
        found = False
        for alt_lang in get_fallback_languages(current_language):
            if alt_lang in available_languages:
                if get_redirect_on_fallback(current_language) or slug == "":
                    with force_language(alt_lang):
                        path = page.get_absolute_url(language=alt_lang,
                                                     fallback=True)
                        # In the case where the page is not available in the
                    # preferred language, *redirect* to the fallback page. This
                    # is a design decision (instead of rendering in place)).
                    if (hasattr(request, 'toolbar') and request.user.is_staff
                            and request.toolbar.edit_mode):
                        request.toolbar.redirect_url = path
                    elif path not in own_urls:
                        return HttpResponseRedirect(path)
                else:
                    found = True
        if not found and (not hasattr(request, 'toolbar')
                          or not request.toolbar.redirect_url):
            # There is a page object we can't find a proper language to render it
            _handle_no_page(request, slug)
    else:
        page_path = page.get_absolute_url(language=current_language)
        page_slug = page.get_path(language=current_language) or page.get_slug(
            language=current_language)

        if slug and slug != page_slug and request.path[:len(page_path
                                                            )] != page_path:
            # The current language does not match it's slug.
            #  Redirect to the current language.
            if hasattr(
                    request, 'toolbar'
            ) and request.user.is_staff and request.toolbar.edit_mode:
                request.toolbar.redirect_url = page_path
            else:
                return HttpResponseRedirect(page_path)

    if apphook_pool.get_apphooks():
        # There are apphooks in the pool. Let's see if there is one for the
        # current page
        # since we always have a page at this point, applications_page_check is
        # pointless
        # page = applications_page_check(request, page, slug)
        # Check for apphooks! This time for real!
        app_urls = page.get_application_urls(current_language, False)
        skip_app = False
        if (not page.is_published(current_language)
                and hasattr(request, 'toolbar') and request.toolbar.edit_mode):
            skip_app = True
        if app_urls and not skip_app:
            app = apphook_pool.get_apphook(app_urls)
            pattern_list = []
            if app:
                for urlpatterns in get_app_urls(
                        app.get_urls(page, current_language)):
                    pattern_list += urlpatterns
                try:
                    view, args, kwargs = resolve('/', tuple(pattern_list))
                    return view(request, *args, **kwargs)
                except Resolver404:
                    pass
    # Check if the page has a redirect url defined for this language.
    redirect_url = page.get_redirect(language=current_language)
    if redirect_url:
        if (is_language_prefix_patterns_used() and redirect_url[0] == "/"
                and not redirect_url.startswith('/%s/' % current_language)):
            # add language prefix to url
            redirect_url = "/%s/%s" % (current_language,
                                       redirect_url.lstrip("/"))
            # prevent redirect to self

        if hasattr(request, 'toolbar'
                   ) and request.user.is_staff and request.toolbar.edit_mode:
            request.toolbar.redirect_url = redirect_url
        elif redirect_url not in own_urls:
            return HttpResponseRedirect(redirect_url)

    # permission checks
    if page.login_required and not request.user.is_authenticated():
        return redirect_to_login(urlquote(request.get_full_path()),
                                 settings.LOGIN_URL)
    if hasattr(request, 'toolbar'):
        request.toolbar.set_object(page)

    response = render_page(request,
                           page,
                           current_language=current_language,
                           slug=slug)
    return response
Beispiel #55
0
 def test_get_fallback_languages(self):
     languages = i18n.get_fallback_languages("en", 1)
     self.assertEqual(languages, ["de", "fr"])
Beispiel #56
0
def details(request, slug):
    """
    The main view of the Django-CMS! Takes a request and a slug, renders the
    page.
    """
    response_timestamp = now()
    if get_cms_setting("PAGE_CACHE") and (
        not hasattr(request, 'toolbar') or (
            not request.toolbar.edit_mode and
            not request.toolbar.show_toolbar and
            not request.user.is_authenticated()
        )
    ):
        cache_content = get_page_cache(request)
        if cache_content is not None:
            content, headers, expires_datetime = cache_content
            response = HttpResponse(content)
            response._headers = headers
            # Recalculate the max-age header for this cached response
            max_age = int(
                (expires_datetime - response_timestamp).total_seconds() + 0.5)
            patch_cache_control(response, max_age=max_age)
            return response

    # Get a Page model object from the request
    page = get_page_from_request(request, use_path=slug)
    if not page:
        return _handle_no_page(request, slug)
    current_language = request.GET.get('language', None)
    if not current_language:
        current_language = request.POST.get('language', None)
    if current_language:
        current_language = get_language_code(current_language)
        if current_language not in get_language_list(page.site_id):
            current_language = None
    if current_language is None:
        current_language = get_language_code(getattr(request, 'LANGUAGE_CODE', None))
        if current_language:
            current_language = get_language_code(current_language)
            if current_language not in get_language_list(page.site_id):
                current_language = None
    if current_language is None:
        current_language = get_language_code(get_language())
    # Check that the current page is available in the desired (current) language
    available_languages = []
    # this will return all languages in draft mode, and published only in live mode
    page_languages = list(page.get_published_languages())
    if hasattr(request, 'user') and request.user.is_staff:
        user_languages = get_language_list()
    else:
        user_languages = get_public_languages()
    for frontend_lang in user_languages:
        if frontend_lang in page_languages:
            available_languages.append(frontend_lang)
    # Check that the language is in FRONTEND_LANGUAGES:
    own_urls = [
        'http%s://%s%s' % ('s' if request.is_secure() else '', request.get_host(), request.path),
        '/%s' % request.path,
        request.path,
    ]
    if current_language not in user_languages:
        #are we on root?
        if not slug:
            #redirect to supported language
            languages = []
            for language in available_languages:
                languages.append((language, language))
            if languages:
                # get supported language
                new_language = get_language_from_request(request)
                if new_language in get_public_languages():
                    with force_language(new_language):
                        pages_root = reverse('pages-root')
                        if (hasattr(request, 'toolbar') and request.user.is_staff and request.toolbar.edit_mode):
                            request.toolbar.redirect_url = pages_root
                        elif pages_root not in own_urls:
                            return HttpResponseRedirect(pages_root)
            elif not hasattr(request, 'toolbar') or not request.toolbar.redirect_url:
                _handle_no_page(request, slug)
        else:
            return _handle_no_page(request, slug)
    if current_language not in available_languages:
        # If we didn't find the required page in the requested (current)
        # language, let's try to find a fallback
        found = False
        for alt_lang in get_fallback_languages(current_language):
            if alt_lang in available_languages:
                if get_redirect_on_fallback(current_language) or slug == "":
                    with force_language(alt_lang):
                        path = page.get_absolute_url(language=alt_lang, fallback=True)
                        # In the case where the page is not available in the
                    # preferred language, *redirect* to the fallback page. This
                    # is a design decision (instead of rendering in place)).
                    if (hasattr(request, 'toolbar') and request.user.is_staff
                            and request.toolbar.edit_mode):
                        request.toolbar.redirect_url = path
                    elif path not in own_urls:
                        return HttpResponseRedirect(path)
                else:
                    found = True
        if not found and (not hasattr(request, 'toolbar') or not request.toolbar.redirect_url):
            # There is a page object we can't find a proper language to render it
            _handle_no_page(request, slug)

    if apphook_pool.get_apphooks():
        # There are apphooks in the pool. Let's see if there is one for the
        # current page
        # since we always have a page at this point, applications_page_check is
        # pointless
        # page = applications_page_check(request, page, slug)
        # Check for apphooks! This time for real!
        app_urls = page.get_application_urls(current_language, False)
        skip_app = False
        if (not page.is_published(current_language) and hasattr(request, 'toolbar')
                and request.toolbar.edit_mode):
            skip_app = True
        if app_urls and not skip_app:
            app = apphook_pool.get_apphook(app_urls)
            pattern_list = []
            if app:
                for urlpatterns in get_app_urls(app.get_urls(page, current_language)):
                    pattern_list += urlpatterns
                try:
                    view, args, kwargs = resolve('/', tuple(pattern_list))
                    return view(request, *args, **kwargs)
                except Resolver404:
                    pass
    # Check if the page has a redirect url defined for this language.
    redirect_url = page.get_redirect(language=current_language)
    if redirect_url:
        if (is_language_prefix_patterns_used() and redirect_url[0] == "/"
                and not redirect_url.startswith('/%s/' % current_language)):
            # add language prefix to url
            redirect_url = "/%s/%s" % (current_language, redirect_url.lstrip("/"))
            # prevent redirect to self

        if hasattr(request, 'toolbar') and request.user.is_staff and request.toolbar.edit_mode:
            request.toolbar.redirect_url = redirect_url
        elif redirect_url not in own_urls:
            return HttpResponseRedirect(redirect_url)

    # permission checks
    if page.login_required and not request.user.is_authenticated():
        return redirect_to_login(urlquote(request.get_full_path()), settings.LOGIN_URL)
    if hasattr(request, 'toolbar'):
        request.toolbar.set_object(page)

    response = render_page(request, page, current_language=current_language, slug=slug)
    return response
Beispiel #57
0
def show_menu(context,
              from_level=0,
              to_level=100,
              extra_inactive=0,
              extra_active=100,
              template="cms/menu.html",
              next_page=None,
              root_id=None):
    """
    render a nested list of all children of the pages
    from_level: is the start level
    to_level: is the max level rendered
    render_children: if set to True will render all not direct ascendants too
    """
    try:
        # If there's an exception (500), default context_processors may not be called.
        request = context['request']
    except KeyError:
        return {'template': 'cms/content.html'}
    page_queryset = get_page_queryset(request)
    site = Site.objects.get_current()
    lang = get_language_from_request(request)
    current_page = request.current_page
    if current_page == "dummy":
        context.update({
            'children': [],
            'template': template,
            'from_level': from_level,
            'to_level': to_level,
            'extra_inactive': extra_inactive,
            'extra_active': extra_active
        })
        return context
    if hasattr(current_page, "home_pk_cache"):
        home_pk = current_page.home_pk_cache
    else:
        try:
            home_pk = page_queryset.get_home(site).pk
        except NoHomeFound:
            home_pk = 0
    if not next_page:  #new menu... get all the data so we can save a lot of queries

        children = []
        ancestors = []
        alist = None
        if current_page:
            alist = current_page.get_ancestors().values_list('id', 'soft_root')
        if not alist:  # == None:# maybe the active node is in an extender?
            alist = []
            extenders = page_queryset.published().filter(in_navigation=True,
                                                         site=site,
                                                         level__lte=to_level)
            extenders = extenders.exclude(
                navigation_extenders__isnull=True).exclude(
                    navigation_extenders__exact="")
            for ext in extenders:
                ext.childrens = []
                ext.ancestors_ascending = []
                get_extended_navigation_nodes(request, 100, [ext], ext.level,
                                              100, 100, False,
                                              ext.navigation_extenders)
                if hasattr(ext, "ancestor"):
                    alist = list(ext.get_ancestors().values_list(
                        'id', 'soft_root'))
                    alist = [(ext.pk, ext.soft_root)] + alist
                    break
        filters = {'in_navigation': True, 'site': site, 'level__lte': to_level}
        #check the ancestors for softroots
        soft_root_pk = None
        for p in alist:
            ancestors.append(p[0])
            if p[1]:
                soft_root_pk = p[0]
        #modify filters if we don't start from the root
        root_page = None
        if root_id:
            try:
                root_page = page_queryset.get(reverse_id=root_id, site=site)
            except:
                send_missing_mail(root_id, request)
        else:
            if current_page and current_page.soft_root:
                root_page = current_page
                soft_root_pk = current_page.pk
            elif soft_root_pk:
                root_page = page_queryset.get(pk=soft_root_pk)
        if root_page:
            if isinstance(root_page, int):
                root_page = page_queryset.get(pk=root_page)
            if isinstance(root_page, Page):
                root_page = page_queryset.get(pk=root_page.id)
            elif isinstance(root_page, unicode):
                root_page = page_queryset.get(reverse_id=root_page, site=site)
            filters['tree_id'] = root_page.tree_id
            filters['lft__gt'] = root_page.lft
            filters['rght__lt'] = root_page.rght
            filters['level__lte'] = root_page.level + to_level
            db_from_level = root_page.level + from_level
        else:
            db_from_level = from_level
        if settings.CMS_HIDE_UNTRANSLATED:
            filters['title_set__language'] = lang
        if not request.user.is_authenticated():
            filters['menu_login_required'] = False
        pages = page_queryset.published().filter(**filters).order_by(
            'tree_id', 'parent', 'lft')
        pages = list(pages)
        if root_page:
            pages = [root_page] + pages
        all_pages = pages[:]
        root_level = getattr(root_page, 'level', None)
        ids = []
        current = None
        for page in pages:  # build the tree
            if current_page and current_page.pk == page.pk:
                current = page
            if page.level >= db_from_level:
                ids.append(page.pk)
            if page.level == 0 or page.level == root_level:
                if page.parent_id:
                    page.get_cached_ancestors()
                else:
                    page.ancestors_ascending = []
                page.home_pk_cache = home_pk
                page.menu_level = 0 - from_level
                page.childrens = []
                children.append(page)
                if page.pk == soft_root_pk:
                    page.soft_root = False  #ugly hack for the recursive function
                if current_page and not current_page.navigation_extenders:
                    pk = current_page.pk
                else:
                    pk = -1
                find_children(page,
                              pages,
                              extra_inactive,
                              extra_active,
                              ancestors,
                              pk,
                              request=request,
                              to_levels=to_level)
                if page.pk == soft_root_pk:
                    page.soft_root = True
        if db_from_level > 0:
            children = cut_levels(children, db_from_level)
        titles = list(
            get_title_queryset(request).filter(page__in=ids, language=lang))
        for page in all_pages:  # add the title and slugs and some meta data
            for title in titles:
                if title.page_id == page.pk:
                    if not hasattr(page, "title_cache"):
                        page.title_cache = {}
                    page.title_cache[title.language] = title
                    ids.remove(page.pk)
            if current_page and page.pk == current_page.pk and not getattr(
                    current, 'ancestor', False):
                page.selected = True
                if hasattr(page, "childrens"):
                    mark_descendants(page.childrens)
            if page.pk in ancestors:
                page.ancestor = True
            if current_page and page.parent_id == current_page.parent_id and not page.pk == current_page.pk and not getattr(
                    current, 'ancestor', False):
                page.sibling = True
        if ids:
            fallbacks = get_fallback_languages(lang)
            for l in fallbacks:
                titles = list(
                    get_title_queryset(request).filter(page__in=ids,
                                                       language=l))
                for page in all_pages:  # add the title and slugs and some meta data
                    for title in titles:
                        if title.page_id == page.pk:
                            if not hasattr(page, "title_cache"):
                                page.title_cache = {}
                            page.title_cache[title.language] = title
                            ids.remove(page.pk)
                if not ids:
                    break
        children = navigation.handle_navigation_manipulators(children, request)
    else:
        children = next_page.childrens
    context.update({
        'children': children,
        'template': template,
        'from_level': from_level,
        'to_level': to_level,
        'extra_inactive': extra_inactive,
        'extra_active': extra_active
    })
    return context
Beispiel #58
0
def get_fallback_languages_for_page(page, current_language, current_user=None, allowed_languages=None):
    if allowed_languages is None:
        allowed_languages = get_languages_for_page_user(page=page, user=current_user)
    return [language for language in get_fallback_languages(current_language) if language in allowed_languages]
Beispiel #59
0
    def get_reverse_related_page_extensions(self,
                                            model_name,
                                            language=None,
                                            include_descendants=False):
        """
        Return a query to get the page extensions of a given model type related to the current
        page extension instance.

        For example: for an organization, it will return all courses that are pointing to this
        organization via an OrganizationPlugin in any placeholder of the course page.
        """
        is_draft = self.extended_object.publisher_is_draft
        # pylint: disable=no-member
        page_extension = self if is_draft else self.draft_extension
        page = page_extension.extended_object
        current_language = language or translation.get_language()
        site = get_current_site()

        languages = [current_language] + i18n.get_fallback_languages(
            current_language, site_id=site.pk)
        languages = list(dict.fromkeys(languages))

        for item in range(len(languages)):
            for previous_item, previous_language in enumerate(languages[:item +
                                                                        1]):

                qop_dict = {
                    "extended_object__placeholders__cmsplugin__language":
                    previous_language
                }
                if previous_item == item:
                    if not is_draft:
                        qop_dict.update({
                            "extended_object__title_set__language":
                            previous_language,
                            "extended_object__title_set__published":
                            True,
                        })
                    qop = models.Q(**qop_dict)
                else:
                    qop = ~models.Q(**qop_dict)

                if previous_item == 0:
                    subclause = qop
                else:
                    subclause &= qop

            if item == 0:
                language_clause = subclause
            else:
                language_clause |= subclause

        self_name = self._meta.model.__name__.lower()
        if include_descendants is True:
            bfs = ("extended_object__placeholders__cmsplugin__"
                   f"courses_{self_name:s}pluginmodel__page__node")
            selector = {
                f"{bfs:s}__path__startswith": page.node.path,
                f"{bfs:s}__depth__gte": page.node.depth,
            }
        else:
            bfs = ("extended_object__placeholders__cmsplugin__courses_"
                   f"{self_name:s}pluginmodel__page")
            selector = {bfs: page}

        page_extension_model = apps.get_model(app_label="courses",
                                              model_name=model_name)
        # pylint: disable=no-member
        return (page_extension_model.objects.filter(
            language_clause,
            extended_object__publisher_is_draft=is_draft,
            **selector,
        ).select_related("extended_object").prefetch_related(
            models.Prefetch(
                "extended_object__title_set",
                to_attr="prefetched_titles",
                queryset=Title.objects.filter(language=current_language),
            )).distinct().order_by("extended_object__node__path"))