Beispiel #1
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
Beispiel #2
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
Beispiel #3
0
def _get_page_by_untyped_arg(page_lookup, request, site_id):
    """
    The `page_lookup` argument can be of any of the following types:
    - Integer: interpreted as `pk` of the desired page
    - String: interpreted as `reverse_id` of the desired page
    - `dict`: a dictionary containing keyword arguments to find the desired page
    (for instance: `{'pk': 1}`)
    - `Page`: you can also pass a Page object directly, in which case there will be no database lookup.
    - `None`: the current page will be used
    """
    if page_lookup is None:
        return request.current_page
    if isinstance(page_lookup, Page):
        if request.current_page and request.current_page.pk == page_lookup.pk:
            return request.current_page
        return page_lookup
    if isinstance(page_lookup, str):
        page_lookup = {'reverse_id': page_lookup}
    elif isinstance(page_lookup, int):
        page_lookup = {'pk': page_lookup}
    elif not isinstance(page_lookup, dict):
        raise TypeError('The page_lookup argument can be either a Dictionary, Integer, Page, or String.')
    site = Site.objects._get_site_by_id(site_id)
    try:
        if 'pk' in page_lookup:
            page = Page.objects.select_related('node').get(**page_lookup)
            if request and use_draft(request):
                if page.publisher_is_draft:
                    return page
                else:
                    return page.publisher_draft
            else:
                if page.publisher_is_draft:
                    return page.publisher_public
                else:
                    return page
        else:
            pages = get_page_queryset(site, draft=use_draft(request))
            return pages.select_related('node').get(**page_lookup)
    except Page.DoesNotExist:
        subject = _('Page not found on %(domain)s') % {'domain': site.domain}
        body = _("A template tag couldn't find the page with lookup arguments `%(page_lookup)s\n`. "
                 "The URL of the request was: http://%(host)s%(path)s") \
               % {'page_lookup': repr(page_lookup), 'host': site.domain, 'path': request.path_info}
        if settings.DEBUG:
            raise Page.DoesNotExist(body)
        else:
            mw = settings.MIDDLEWARE
            if getattr(settings, 'SEND_BROKEN_LINK_EMAILS', False):
                mail_managers(subject, body, fail_silently=True)
            elif 'django.middleware.common.BrokenLinkEmailsMiddleware' in mw:
                middle = BrokenLinkEmailsMiddleware()
                domain = request.get_host()
                path = request.get_full_path()
                referer = force_str(request.META.get('HTTP_REFERER', ''), errors='replace')
                if not middle.is_ignorable_request(request, path, domain, referer):
                    mail_managers(subject, body, fail_silently=True)
            return None
Beispiel #4
0
def applications_page_check(request, current_page=None, path=None):
    """Tries to find if given path was resolved over application.
    Applications have higher priority than other cms pages.
    """
    if current_page:
        return current_page
    if path is None:
        # We should get in this branch only if an apphook is active on /
        # This removes the non-CMS part of the URL.
        path = request.path_info.replace(reverse('pages-root'), '', 1)
        # check if application resolver can resolve this
    for lang in get_language_list():
        if path.startswith(lang + "/"):
            path = path[len(lang + "/"):]

    use_public = not use_draft(request)

    for resolver in APP_RESOLVERS:
        try:
            page_id = resolver.resolve_page_id(path)
            # yes, it is application page
            page = Page.objects.public().get(id=page_id)
            # If current page was matched, then we have some override for
            # content from cms, but keep current page. Otherwise return page
            # to which was application assigned.
            return page if use_public else page.publisher_public
        except Resolver404:
            # Raised if the page is not managed by an apphook
            pass
        except Page.DoesNotExist:
            pass
    return None
Beispiel #5
0
def get_page_from_request(request, use_path=None, clean_path=None):
    """
    Gets the current page from a request object.

    URLs can be of the following form (this should help understand the code):
    http://server.whatever.com/<some_path>/"pages-root"/some/page/slug

    <some_path>: This can be anything, and should be stripped when resolving
        pages names. This means the CMS is not installed at the root of the
        server's URLs.
    "pages-root" This is the root of Django urls for the CMS. It is, in essence
        an empty page slug (slug == '')

    The page slug can then be resolved to a Page model object
    """
    from cms.utils.page_permissions import user_can_view_page_draft

    if hasattr(request, '_current_page_cache'):
        # The following is set by CurrentPageMiddleware
        return request._current_page_cache

    if clean_path is None:
        clean_path = not bool(use_path)

    draft = use_draft(request)
    preview = 'preview' in request.GET
    path = request.path_info if use_path is None else use_path

    if clean_path:
        pages_root = reverse("pages-root")

        if path.startswith(pages_root):
            path = path[len(pages_root):]

        # strip any final slash
        if path.endswith("/"):
            path = path[:-1]

    site = get_current_site()
    page = get_page_from_path(site, path, preview, draft)

    if draft and page and not user_can_view_page_draft(request.user, page):
        page = get_page_from_path(site, path, preview, draft=False)

    # For public pages, check if any parent is hidden due to published dates
    # In this case the selected page is not reachable
    if page and not draft:
        now = timezone.now()
        unpublished_ancestors = (
            page
            .get_ancestor_pages()
            .filter(
                Q(publication_date__gt=now)
                | Q(publication_end_date__lt=now),
            )
        )
        if unpublished_ancestors.exists():
            page = None
    return page
Beispiel #6
0
 def get_queryset(self):
     site = get_current_site(self.request)
     if self.action == 'menu':
         return menu_pool.get_nodes(self.request, site_id=site.pk)
     if use_draft(self.request):
         return Page.objects.drafts().on_site(site=site).distinct()
     else:
         return Page.objects.public().on_site(site=site).distinct()
Beispiel #7
0
 def get_queryset(self):
     site = get_current_site(self.request)
     if self.action == 'menu':
         return menu_pool.get_nodes(self.request, site_id=site.pk)
     if use_draft(self.request):
         return Page.objects.drafts().on_site(site=site).distinct()
     else:
         return Page.objects.public().on_site(site=site).distinct()
Beispiel #8
0
def _get_page_by_untyped_arg(page_lookup, request, site_id):
    """
    The `page_lookup` argument can be of any of the following types:
    - Integer: interpreted as `pk` of the desired page
    - String: interpreted as `reverse_id` of the desired page
    - `dict`: a dictionary containing keyword arguments to find the desired page
    (for instance: `{'pk': 1}`)
    - `Page`: you can also pass a Page object directly, in which case there will be no database lookup.
    - `None`: the current page will be used
    """
    if page_lookup is None:
        return request.current_page
    if isinstance(page_lookup, Page):
        if request.current_page and request.current_page.pk == page_lookup.pk:
            return request.current_page
        return page_lookup
    if isinstance(page_lookup, six.string_types):
        page_lookup = {'reverse_id': page_lookup}
    elif isinstance(page_lookup, six.integer_types):
        page_lookup = {'pk': page_lookup}
    elif not isinstance(page_lookup, dict):
        raise TypeError('The page_lookup argument can be either a Dictionary, Integer, Page, or String.')
    page_lookup.update({'site': site_id})
    try:
        if 'pk' in page_lookup:
            page = Page.objects.all().get(**page_lookup)
            if request and use_draft(request):
                if page.publisher_is_draft:
                    return page
                else:
                    return page.publisher_draft
            else:
                if page.publisher_is_draft:
                    return page.publisher_public
                else:
                    return page
        else:
            return get_page_queryset(request).get(**page_lookup)
    except Page.DoesNotExist:
        site = Site.objects.get_current()
        subject = _('Page not found on %(domain)s') % {'domain': site.domain}
        body = _("A template tag couldn't find the page with lookup arguments `%(page_lookup)s\n`. "
                 "The URL of the request was: http://%(host)s%(path)s") \
               % {'page_lookup': repr(page_lookup), 'host': site.domain, 'path': request.path_info}
        if settings.DEBUG:
            raise Page.DoesNotExist(body)
        else:
            mw = get_middleware()
            if getattr(settings, 'SEND_BROKEN_LINK_EMAILS', False):
                mail_managers(subject, body, fail_silently=True)
            elif 'django.middleware.common.BrokenLinkEmailsMiddleware' in mw:
                middle = BrokenLinkEmailsMiddleware()
                domain = request.get_host()
                path = request.get_full_path()
                referer = force_text(request.META.get('HTTP_REFERER', ''), errors='replace')
                if not middle.is_ignorable_request(request, path, domain, referer):
                    mail_managers(subject, body, fail_silently=True)
            return None
Beispiel #9
0
 def draft_mode_active(self):
     try:
         # Under certain conditions, the request page won't match
         # the requested state.
         # For example, user requests draft page but gets public.
         _use_draft = self.request.current_page.publisher_is_draft
     except AttributeError:
         _use_draft = use_draft(self.request)
     return _use_draft
def get_page_from_request(request, use_path=None):
    """
    Gets the current page from a request object.

    URLs can be of the following form (this should help understand the code):
    http://server.whatever.com/<some_path>/"pages-root"/some/page/slug

    <some_path>: This can be anything, and should be stripped when resolving
        pages names. This means the CMS is not installed at the root of the
        server's URLs.
    "pages-root" This is the root of Django urls for the CMS. It is, in essence
        an empty page slug (slug == '')

    The page slug can then be resolved to a Page model object
    """

    # The following is used by cms.middleware.page.CurrentPageMiddleware
    if hasattr(request, '_current_page_cache'):
        return request._current_page_cache

    draft = use_draft(request)
    preview = 'preview' in request.GET
    # If use_path is given, someone already did the path cleaning
    if use_path is not None:
        path = use_path
    else:
        path = request.path_info
        pages_root = unquote(reverse("pages-root"))
        # otherwise strip off the non-cms part of the URL
        if is_installed('django.contrib.admin'):
            admin_base = admin_reverse('index')
        else:
            admin_base = None
        if path.startswith(pages_root) and (not admin_base or
                                            not path.startswith(admin_base)):
            path = path[len(pages_root):]
            # and strip any final slash
        if path.endswith("/"):
            path = path[:-1]

    page = get_page_from_path(path, preview, draft)

    if draft and page and not user_can_change_page(request.user, page):
        page = get_page_from_path(path, preview, draft=False)

    # For public pages we check if any parent is hidden due to published dates
    # In this case the selected page is not reachable
    if page and not draft:
        ancestors = page.get_ancestors().filter(
            Q(publication_date__gt=timezone.now())
            | Q(publication_end_date__lt=timezone.now()), )
        if ancestors.exists():
            page = None

    request._current_page_cache = page
    return page
    def get_context(self, context, menu_name_or_slug, from_level, to_level, extra_inactive,
                    extra_active, template, namespace, root_id, next_page):

        # From menus.template_tags.menu_tags.py
        try:
            # If there's an exception (500), default context_processors may not be called.
            request = context['request']
        except KeyError:
            return {'template': 'menu/empty.html'}

        if next_page:
            children = next_page.children
        else:

            # new menu... get all the data so we can save a lot of queries
            menu_renderer = context.get('cms_menu_renderer')

            if not menu_renderer:
                menu_renderer = menu_pool.get_renderer(request)

            # Get Nodes hopefully from cached page nodes above in context
            nodes = menu_renderer.get_nodes(namespace, root_id)
            nodes = filter_nodes(nodes)

            # Ceate a page_node dictionary
            page_nodes = {n.id: n for n in nodes}

            # Get if in Draft or Published mode
            draft_mode_active = use_draft(request)

            # Build or get from cache - Named menu nodes
            nodes = build_named_menu_nodes(menu_name_or_slug, page_nodes, draft_mode_active, namespace=namespace)

            # If nodes returned, then cut levels and apply modifiers
            if nodes:
                # Post-Cut ... apply cut levels and menu modifiers
                nodes = flatten(nodes)
                children = cut_levels(nodes, from_level, to_level, extra_inactive, extra_active)
                children = menu_renderer.apply_modifiers(children, namespace, root_id, post_cut=True)
            else:
                children = []

        # Return the context, or go straight to template which will present missing etc.
        try:
            context['children'] = children
            context['template'] = template
            context['from_level'] = from_level
            context['to_level'] = to_level
            context['extra_inactive'] = extra_inactive
            context['extra_active'] = extra_active
            context['namespace'] = namespace
        except:
            context = {"template": template}

        return context
Beispiel #12
0
def get_page_from_request(request, use_path=None):
    """
    Gets the current page from a request object.

    URLs can be of the following form (this should help understand the code):
    http://server.whatever.com/<some_path>/"pages-root"/some/page/slug

    <some_path>: This can be anything, and should be stripped when resolving
        pages names. This means the CMS is not installed at the root of the
        server's URLs.
    "pages-root" This is the root of Django urls for the CMS. It is, in essence
        an empty page slug (slug == '')

    The page slug can then be resolved to a Page model object
    """

    # The following is used by cms.middleware.page.CurrentPageMiddleware
    if hasattr(request, '_current_page_cache'):
        return request._current_page_cache

    draft = use_draft(request)
    preview = 'preview' in request.GET
    # If use_path is given, someone already did the path cleaning
    if use_path is not None:
        path = use_path
    else:
        path = request.path_info
        pages_root = unquote(reverse("pages-root"))
        # otherwise strip off the non-cms part of the URL
        if is_installed('django.contrib.admin'):
            admin_base = admin_reverse('index')
        else:
            admin_base = None
        if path.startswith(pages_root) and (not admin_base or not path.startswith(admin_base)):
            path = path[len(pages_root):]
            # and strip any final slash
        if path.endswith("/"):
            path = path[:-1]

    page = get_page_from_path(path, preview, draft)

    if draft and page and not user_can_change_page(request.user, page):
        page = get_page_from_path(path, preview, draft=False)

    # For public pages we check if any parent is hidden due to published dates
    # In this case the selected page is not reachable
    if page and not draft:
        ancestors = page.get_ancestors().filter(
            Q(publication_date__gt=timezone.now()) | Q(publication_end_date__lt=timezone.now()),
        )
        if ancestors.exists():
            page = None

    request._current_page_cache = page
    return page
Beispiel #13
0
 def __init__(self, pool, request):
     self.pool = pool
     # It's important this happens on init
     # because we need to make sure that a menu renderer
     # points to the same registered menus as long as the
     # instance lives.
     self.menus = pool.get_registered_menus(for_rendering=True)
     self.request = request
     self.language = get_language_from_request(request)
     self.site = Site.objects.get_current(request)
     self.draft_mode_active = use_draft(request)
def _get_article_by_untyped_arg(article_lookup, request, site_id):
    """
    The `article_lookup` argument can be of any of the following types:
    - Integer: interpreted as `pk` of the desired article
    - `dict`: a dictionary containing keyword arguments to find the desired article
    (for instance: `{'pk': 1}`)
    - `Article`: you can also pass an Article object directly, in which case there will be no database lookup.
    - `None`: the current article will be used
    """
    if article_lookup is None:
        return request.current_article
    if isinstance(article_lookup, Article):
        if hasattr(request, 'current_article') and request.current_article.pk == article_lookup.pk:
            return request.current_article
        return article_lookup
    if isinstance(article_lookup, six.integer_types):
        article_lookup = {'pk': article_lookup}
    elif not isinstance(article_lookup, dict):
        raise TypeError('The article_lookup argument can be either a Dictionary, Integer, or Article.')
    article_lookup.update({'site': site_id})
    try:
        article = Article.objects.all().get(**article_lookup)
        if request and use_draft(request):
            if article.publisher_is_draft:
                return article
            else:
                return article.publisher_draft
        else:
            if article.publisher_is_draft:
                return article.publisher_public
            else:
                return article
    except Article.DoesNotExist:
        site = Site.objects.get_current()
        subject = _('Article not found on %(domain)s') % {'domain': site.domain}
        body = (
            _("A template tag couldn't find the article with lookup arguments `%(article_lookup)s\n`. "
              "The URL of the request was: http://%(host)s%(path)s") %
            {'article_lookup': repr(article_lookup), 'host': site.domain, 'path': request.path_info}
        )
        if settings.DEBUG:
            raise Article.DoesNotExist(body)
        else:
            mw = get_middleware()
            if getattr(settings, 'SEND_BROKEN_LINK_EMAILS', False):
                mail_managers(subject, body, fail_silently=True)
            elif 'django.middleware.common.BrokenLinkEmailsMiddleware' in mw:
                middle = BrokenLinkEmailsMiddleware()
                domain = request.get_host()
                path = request.get_full_path()
                referer = force_text(request.META.get('HTTP_REFERER', ''), errors='replace')
                if not middle.is_ignorable_request(request, path, domain, referer):
                    mail_managers(subject, body, fail_silently=True)
            return None
Beispiel #15
0
 def __init__(self, pool, request):
     self.pool = pool
     # It's important this happens on init
     # because we need to make sure that a menu renderer
     # points to the same registered menus as long as the
     # instance lives.
     self.menus = pool.get_registered_menus(for_rendering=True)
     self.request = request
     self.request_language = get_language_from_request(request, check_path=True)
     self.site = Site.objects.get_current(request)
     self.draft_mode_active = use_draft(request)
Beispiel #16
0
    def get(self, request, **kwargs):
        draft = use_draft(request)
        preview = 'preview' in request.GET
        try:
            self.cms_page = get_page_from_path(kwargs.get('path', ''), preview,
                                               draft)
            self.cms_page_title = self.cms_page.title_set.get(
                language=request.LANGUAGE_CODE)
        except AttributeError:
            return JsonResponse(data={}, status=404)

        return super(SpaCmsPageDetailApiView, self).get(request, **kwargs)
Beispiel #17
0
def _get_page_by_untyped_arg(page_lookup, request, site_id):
    """
    The `page_lookup` argument can be of any of the following types:
    - Integer: interpreted as `pk` of the desired page
    - String: interpreted as `reverse_id` of the desired page
    - `dict`: a dictionary containing keyword arguments to find the desired page
    (for instance: `{'pk': 1}`)
    - `Page`: you can also pass a Page object directly, in which case there will be no database lookup.
    - `None`: the current page will be used
    """
    if page_lookup is None:
        return request.current_page
    if isinstance(page_lookup, Page):
        if request.current_page and request.current_page.pk == page_lookup.pk:
            return request.current_page
        return page_lookup
    if isinstance(page_lookup, six.string_types):
        page_lookup = {'reverse_id': page_lookup}
    elif isinstance(page_lookup, six.integer_types):
        page_lookup = {'pk': page_lookup}
    elif not isinstance(page_lookup, dict):
        raise TypeError(
            'The page_lookup argument can be either a Dictionary, Integer, Page, or String.'
        )
    page_lookup.update({'site': site_id})
    try:
        if 'pk' in page_lookup:
            page = Page.objects.all().get(**page_lookup)
            if request and use_draft(request):
                if page.publisher_is_draft:
                    return page
                else:
                    return page.publisher_draft
            else:
                if page.publisher_is_draft:
                    return page.publisher_public
                else:
                    return page
        else:
            return get_page_queryset(request).get(**page_lookup)
    except Page.DoesNotExist:
        site = Site.objects.get_current()
        subject = _('Page not found on %(domain)s') % {'domain': site.domain}
        body = _("A template tag couldn't find the page with lookup arguments `%(page_lookup)s\n`. "
                 "The URL of the request was: http://%(host)s%(path)s") \
               % {'page_lookup': repr(page_lookup), 'host': site.domain, 'path': request.path_info}
        if settings.DEBUG:
            raise Page.DoesNotExist(body)
        else:
            if settings.SEND_BROKEN_LINK_EMAILS:
                mail_managers(subject, body, fail_silently=True)
            return None
Beispiel #18
0
def _get_page_by_untyped_arg(page_lookup, request, site_id):
    """
    The `page_lookup` argument can be of any of the following types:
    - Integer: interpreted as `pk` of the desired page
    - String: interpreted as `reverse_id` of the desired page
    - `dict`: a dictionary containing keyword arguments to find the desired page
    (for instance: `{'pk': 1}`)
    - `Page`: you can also pass a Page object directly, in which case there will be no database lookup.
    - `None`: the current page will be used
    """
    if page_lookup is None:
        return request.current_page
    if isinstance(page_lookup, Page):
        if request.current_page and request.current_page.pk == page_lookup.pk:
            return request.current_page
        return page_lookup
    if isinstance(page_lookup, string_types):
        page_lookup = {'reverse_id': page_lookup}
    elif isinstance(page_lookup, int_types):
        page_lookup = {'pk': page_lookup}
    elif not isinstance(page_lookup, dict):
        raise TypeError('The page_lookup argument can be either a Dictionary, Integer, Page, or String.')
    page_lookup.update({'site': site_id})
    try:
        if 'pk' in page_lookup:
            page = Page.objects.all().get(**page_lookup)
            if request and use_draft(request):
                if page.publisher_is_draft:
                    return page
                else:
                    return page.publisher_draft
            else:
                if page.publisher_is_draft:
                    return page.publisher_public
                else:
                    return page
        else:
            return get_page_queryset(request).get(**page_lookup)
    except Page.DoesNotExist:
        site = Site.objects.get_current()
        subject = _('Page not found on %(domain)s') % {'domain': site.domain}
        body = _("A template tag couldn't find the page with lookup arguments `%(page_lookup)s\n`. "
                 "The URL of the request was: http://%(host)s%(path)s") \
               % {'page_lookup': repr(page_lookup), 'host': site.domain, 'path': request.path}
        if settings.DEBUG:
            raise Page.DoesNotExist(body)
        else:
            if settings.SEND_BROKEN_LINK_EMAILS:
                mail_managers(subject, body, fail_silently=True)
            return None
def get_page_from_request(request, use_path=None):
    """
    Gets the current page from a request object.
    
    URLs can be of the following form (this should help understand the code):
    http://server.whatever.com/<some_path>/"pages-root"/some/page/slug
    
    <some_path>: This can be anything, and should be stripped when resolving
        pages names. This means the CMS is not installed at the root of the 
        server's URLs.
    "pages-root" This is the root of Django urls for the CMS. It is, in essence
        an empty page slug (slug == '')
        
    The page slug can then be resolved to a Page model object
    """

    # The following is used by cms.middleware.page.CurrentPageMiddleware
    if hasattr(request, '_current_page_cache'):
        return request._current_page_cache

    draft = use_draft(request)
    preview = 'preview' in request.GET

    # If use_path is given, someone already did the path cleaning
    if use_path is not None:
        path = use_path
    else:
        path = request.path
        pages_root = unquote(reverse("pages-root"))
        # otherwise strip off the non-cms part of the URL
        if 'django.contrib.admin' in settings.INSTALLED_APPS:
            admin_base = reverse('admin:index')
        else:
            admin_base = None
        if path.startswith(pages_root) and (not admin_base or
                                            not path.startswith(admin_base)):
            path = path[len(pages_root):]
            # and strip any final slash
        if path.endswith("/"):
            path = path[:-1]

    page = get_page_from_path(path, preview, draft)
    if draft and page and not page.has_change_permission(request):
        page = get_page_from_path(path, preview, draft=False)

    request._current_page_cache = page
    return page
Beispiel #20
0
def get_page_from_request(request, use_path=None):
    """
    Gets the current page from a request object.
    
    URLs can be of the following form (this should help understand the code):
    http://server.whatever.com/<some_path>/"pages-root"/some/page/slug
    
    <some_path>: This can be anything, and should be stripped when resolving
        pages names. This means the CMS is not installed at the root of the 
        server's URLs.
    "pages-root" This is the root of Django urls for the CMS. It is, in essence
        an empty page slug (slug == '')
        
    The page slug can then be resolved to a Page model object
    """

    # The following is used by cms.middleware.page.CurrentPageMiddleware
    if hasattr(request, '_current_page_cache'):
        return request._current_page_cache

    draft = use_draft(request)
    preview = 'preview' in request.GET

    # If use_path is given, someone already did the path cleaning
    if use_path is not None:
        path = use_path
    else:
        path = request.path
        pages_root = unquote(reverse("pages-root"))
        # otherwise strip off the non-cms part of the URL
        if 'django.contrib.admin' in settings.INSTALLED_APPS:
            admin_base = reverse('admin:index')
        else:
            admin_base = None
        if path.startswith(pages_root) and (not admin_base or not path.startswith(admin_base)):
            path = path[len(pages_root):]
            # and strip any final slash
        if path.endswith("/"):
            path = path[:-1]

    page = get_page_from_path(path, preview, draft)
    if draft and page and not page.has_change_permission(request):
        page = get_page_from_path(path, preview, draft=False)

    request._current_page_cache = page
    return page
Beispiel #21
0
def page_titleextension(context, page_id, extension, do_cache=None):
    do_cache = is_caching_desired(do_cache=do_cache)
    request = context.get('request')
    is_draft = request and hasattr(request, 'user') and use_draft(request)

    if do_cache:
        lang = get_language()
        site_id = settings.SITE_ID
        cache_duration = get_cms_setting('CACHE_DURATIONS')['content']
        page_cache_key = _get_cache_key('page_titleextension', page_id, lang, site_id)
        cache_key = '{}_{}_{}'.format(page_cache_key, is_draft, extension)

        cached = cache.get(cache_key)
        if cached:
            if cached == NO_EXTENSION:
                return None
            return cached

    try:
        page = Page.objects.get(pk=page_id)
        if is_draft:
            page = page.get_draft_object()
        else:
            page = page.get_public_object()
    except NameError:
        raise ImportError(
            'django-cms is required when using page_titleextension tag')
    except Page.DoesNotExist:
        return None

    if not page:
        return None

    try:
        title_extension = getattr(page.get_title_obj(), extension)
    except ObjectDoesNotExist:
        if do_cache:
            cache.set(cache_key, NO_EXTENSION, timeout=cache_duration)
        return None
    else:
        if do_cache:
            cache.set(cache_key, title_extension, timeout=cache_duration)
        return title_extension
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 #23
0
def get_page_queryset(request=None):
    if request and use_draft(request):
        return Page.objects.drafts()

    return Page.objects.public()
Beispiel #24
0
def get_page_queryset(request=None):
    if request and use_draft(request):
        return Page.objects.drafts()

    return Page.objects.public()
Beispiel #25
0
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.get_public_object()

    # 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)