Esempio n. 1
0
    def set_helpers(self, context):
        """
        Called from the ``page_menu`` template tag and assigns a
        handful of properties based on the current page, that are used
        within the various types of menus.
        """
        current_page = context["_current_page"]
        current_page_id = getattr(current_page, "id", None)
        current_parent_id = getattr(current_page, "parent_id", None)
        # Am I a child of the current page?
        self.is_current_child = self.parent_id == current_page_id
        self.is_child = self.is_current_child  # Backward compatibility
        # Is my parent the same as the current page's?
        self.is_current_sibling = self.parent_id == current_parent_id
        # Am I the current page?
        try:
            request = context["request"]
        except KeyError:
            # No request context, most likely when tests are run.
            self.is_current = False
        else:
            self.is_current = self.slug == path_to_slug(request.path_info)

        # Is the current page me or any page up the parent chain?
        def is_c_or_a(page_id):
            parent_id = context.get("_parent_page_ids", {}).get(page_id)
            return self.id == page_id or (parent_id and is_c_or_a(parent_id))
        self.is_current_or_ascendant = lambda: bool(is_c_or_a(current_page_id))
        self.is_current_parent = self.id == current_parent_id
        # Am I a primary page?
        self.is_primary = self.parent_id is None
        # What's an ID I can use in HTML?
        self.html_id = self.slug.replace("/", "-")
        # Default branch level - gets assigned in the page_menu tag.
        self.branch_level = 0
Esempio n. 2
0
    def process_view(self, request, view_func, view_args, view_kwargs):
        """
        Per-request mechanics for the current page object.
        """

        # Load the closest matching page by slug, and assign it to the
        # request object. If none found, skip all further processing.
        slug = path_to_slug(request.path_info)
        pages = Page.objects.with_ascendants_for_slug(
            slug, for_user=request.user, include_login_required=True)
        if pages:
            page = pages[0]
            setattr(request, "page", page)
            context_processors.page(request)
        else:
            return

        # Handle ``page.login_required``.
        if page.login_required and not request.user.is_authenticated():
            return redirect_to_login(request.get_full_path())

        # If the view isn't Mezzanine's page view, try to return the result
        # immediately. In the case of a 404 with an URL slug that matches a
        # page exactly, swallow the exception and try Mezzanine's page view.
        #
        # This allows us to set up pages with URLs that also match non-page
        # urlpatterns. For example, a page could be created with the URL
        # /blog/about/, which would match the blog urlpattern, and assuming
        # there wasn't a blog post with the slug "about", would raise a 404
        # and subsequently be rendered by Mezzanine's page view.
        if view_func != page_view:
            try:
                return view_func(request, *view_args, **view_kwargs)
            except Http404:
                if page.slug != slug:
                    raise

        # Run page processors.
        extra_context = {}
        model_processors = page_processors.processors[page.content_model]
        slug_processors = page_processors.processors["slug:%s" % page.slug]
        for (processor, exact_page) in slug_processors + model_processors:
            if exact_page and not page.is_current:
                continue
            processor_response = processor(request, page)
            if isinstance(processor_response, HttpResponse):
                return processor_response
            elif processor_response:
                try:
                    for k, v in processor_response.items():
                        if k not in extra_context:
                            extra_context[k] = v
                except (TypeError, ValueError):
                    name = "%s.%s" % (processor.__module__, processor.__name__)
                    error = ("The page processor %s returned %s but must "
                             "return HttpResponse or dict." %
                             (name, type(processor_response)))
                    raise ValueError(error)

        return page_view(request, slug, extra_context=extra_context)
Esempio n. 3
0
    def set_helpers(self, context):
        """
        Called from the ``page_menu`` template tag and assigns a
        handful of properties based on the current page, that are used
        within the various types of menus.
        """
        current_page = context["_current_page"]
        current_page_id = getattr(current_page, "id", None)
        current_parent_id = getattr(current_page, "parent_id", None)
        # Am I a child of the current page?
        self.is_current_child = self.parent_id == current_page_id
        self.is_child = self.is_current_child  # Backward compatibility
        # Is my parent the same as the current page's?
        self.is_current_sibling = self.parent_id == current_parent_id
        # Am I the current page?
        try:
            request = context["request"]
        except KeyError:
            # No request context, most likely when tests are run.
            self.is_current = False
        else:
            self.is_current = self.slug == path_to_slug(request.path_info)

        # Is the current page me or any page up the parent chain?
        def is_c_or_a(page_id):
            parent_id = context["_parent_page_ids"].get(page_id)
            return self.id == page_id or (parent_id and is_c_or_a(parent_id))
        self.is_current_or_ascendant = lambda: bool(is_c_or_a(current_page_id))
        # Am I a primary page?
        self.is_primary = self.parent_id is None
        # What's an ID I can use in HTML?
        self.html_id = self.slug.replace("/", "-")
        # Default branch level - gets assigned in the page_menu tag.
        self.branch_level = 0
Esempio n. 4
0
    def process_view(self, request, view_func, view_args, view_kwargs):
        """
        Per-request mechanics for the current page object.
        """

        # Load the closest matching page by slug, and assign it to the
        # request object. If none found, skip all further processing.
        slug = path_to_slug(request.path_info)
        pages = Page.objects.with_ascendants_for_slug(slug,
                        for_user=request.user, include_login_required=True)
        if pages:
            page = pages[0]
            setattr(request, "page", page)
            context_processors.page(request)
        else:
            return

        # Handle ``page.login_required``.
        if page.login_required and not request.user.is_authenticated():
            return redirect_to_login(request.get_full_path())

        # If the view isn't Mezzanine's page view, try to return the result
        # immediately. In the case of a 404 with an URL slug that matches a
        # page exactly, swallow the exception and try Mezzanine's page view.
        #
        # This allows us to set up pages with URLs that also match non-page
        # urlpatterns. For example, a page could be created with the URL
        # /blog/about/, which would match the blog urlpattern, and assuming
        # there wasn't a blog post with the slug "about", would raise a 404
        # and subsequently be rendered by Mezzanine's page view.
        if view_func != page_view:
            try:
                return view_func(request, *view_args, **view_kwargs)
            except Http404:
                if page.slug != slug:
                    raise

        # Run page processors.
        extra_context = {}
        model_processors = page_processors.processors[page.content_model]
        slug_processors = page_processors.processors["slug:%s" % page.slug]
        for (processor, exact_page) in slug_processors + model_processors:
            if exact_page and not page.is_current:
                continue
            processor_response = processor(request, page)
            if isinstance(processor_response, HttpResponse):
                return processor_response
            elif processor_response:
                try:
                    for k, v in processor_response.items():
                        if k not in extra_context:
                            extra_context[k] = v
                except (TypeError, ValueError):
                    name = "%s.%s" % (processor.__module__, processor.__name__)
                    error = ("The page processor %s returned %s but must "
                             "return HttpResponse or dict." %
                             (name, type(processor_response)))
                    raise ValueError(error)

        return page_view(request, slug, extra_context=extra_context)
Esempio n. 5
0
    def get_extra_context(self, request):
        slug = path_to_slug(request.path_info)
        # Links may have slugs that begin and end in '/'
        parts = slug.split("/")
        slugs = ["/".join(parts[:i]) for i in range(1, len(parts) + 1)]
        slugs = ['/' + i + '/' for i in slugs] + slugs

        pages = Page.objects.published(
            for_user=request.user,
            include_login_required=True
        ).filter(
            slug__in=slugs
        ).order_by(
            '-slug'
        )

        if pages:
            page = pages[0]
            context = {
                'page': page,
                '_current_page': page,
            }
            page.set_helpers(context)
            return context
        else:
            return {}
Esempio n. 6
0
    def process_view(self, request, view_func, view_args, view_kwargs):

        slug = path_to_slug(request.path_info)
        pages = Page.objects.with_ascendants_for_slug(slug,
                        for_user=request.user, include_login_required=True)
        if pages:
            page = pages[0]
        else:
            # If we can't find a page matching this slug or any
            # of its sub-slugs, skip all further processing.
            return view_func(request, *view_args, **view_kwargs)

        # Handle ``page.login_required``.
        if page.login_required and not request.user.is_authenticated():
            path = urlquote(request.get_full_path())
            bits = (settings.LOGIN_URL, REDIRECT_FIELD_NAME, path)
            return redirect("%s?%s=%s" % bits)

        if page.slug == slug and view_func == page_view:
            # Add the page to the ``extra_context`` arg for the
            # page view, which is responsible for choosing which
            # template to use, and raising 404 if there's no page
            # instance loaded.
            view_kwargs.setdefault("extra_context", {})
            view_kwargs["extra_context"]["page"] = page

        # Create the response, and check that we can add context
        # to it. If not, it's something like a redirect, so we
        # just return it.
        response = view_func(request, *view_args, **view_kwargs)
        if not hasattr(response, "context_data"):
            return response

        # Add the page to its template context, and set helper
        # attributes like ``is_current``.
        response.context_data["page"] = page
        response.context_data["_current_page"] = page
        page.set_helpers(response.context_data)

        # Run page processors.
        model_processors = page_processors.processors[page.content_model]
        slug_processors = page_processors.processors["slug:%s" % page.slug]
        for (processor, exact_page) in slug_processors + model_processors:
            if exact_page and not page.is_current:
                continue
            processor_response = processor(request, page)
            if isinstance(processor_response, HttpResponse):
                return processor_response
            elif processor_response:
                try:
                    response.context_data.update(processor_response)
                except (TypeError, ValueError):
                    name = "%s.%s" % (processor.__module__, processor.__name__)
                    error = ("The page processor %s returned %s but must "
                             "return HttpResponse or dict." %
                             (name, type(processor_response)))
                    raise ValueError(error)

        return response
Esempio n. 7
0
    def process_view(self, request, view_func, view_args, view_kwargs):

        slug = path_to_slug(request.path_info)
        pages = Page.objects.with_ascendants_for_slug(slug, request.user)
        if pages:
            page = pages[0]
        else:
            # If we can't find a page matching this slug or any
            # of its sub-slugs, skip all further processing.
            return view_func(request, *view_args, **view_kwargs)

        # Handle ``page.login_required``.
        if page.login_required and not request.user.is_authenticated():
            path = urlquote(request.get_full_path())
            bits = (settings.LOGIN_URL, REDIRECT_FIELD_NAME, path)
            return redirect("%s?%s=%s" % bits)

        if page.slug == slug and view_func == page_view:
            # Add the page to the ``extra_context`` arg for the
            # page view, which is responsible for choosing which
            # template to use, and raising 404 if there's no page
            # instance loaded.
            view_kwargs.setdefault("extra_context", {})
            view_kwargs["extra_context"]["page"] = page

        # Create the response, and check that we can add context
        # to it. If not, it's something like a redirect, so we
        # just return it.
        response = view_func(request, *view_args, **view_kwargs)
        if not hasattr(response, "context_data"):
            return response

        # Add the page to its template context, and set helper
        # attributes like ``is_current``.
        response.context_data["page"] = page
        response.context_data["_current_page"] = page
        page.set_helpers(response.context_data)

        # Run page processors.
        model_processors = page_processors.processors[page.content_model]
        slug_processors = page_processors.processors["slug:%s" % page.slug]
        for (processor, exact_page) in slug_processors + model_processors:
            if exact_page and not page.is_current:
                continue
            processor_response = processor(request, page)
            if isinstance(processor_response, HttpResponse):
                return processor_response
            elif processor_response:
                try:
                    response.context_data.update(processor_response)
                except (TypeError, ValueError):
                    name = "%s.%s" % (processor.__module__, processor.__name__)
                    error = ("The page processor %s returned %s but must "
                             "return HttpResponse or dict." %
                             (name, type(processor_response)))
                    raise ValueError(error)

        return response
Esempio n. 8
0
    def get_extra_context(self, request):
        slug = path_to_slug(request.path_info)
        # Links may have slugs that begin and end in '/'
        parts = slug.split("/")
        slugs = ["/".join(parts[:i]) for i in range(1, len(parts) + 1)]
        slugs = ['/' + i + '/' for i in slugs] + slugs

        pages = Page.objects.published(for_user=request.user,
                                       include_login_required=True).filter(
                                           slug__in=slugs).order_by('-slug')

        if pages:
            page = pages[0]
            context = {
                'page': page,
                '_current_page': page,
            }
            page.set_helpers(context)
            return context
        else:
            return {}
Esempio n. 9
0
    def process_view(self, request, view_func, view_args, view_kwargs):

        slug = path_to_slug(request.path_info)
        pages = Page.objects.with_ascendants_for_slug(slug,
                        for_user=request.user, include_login_required=True)
        if pages:
            page = pages[0]
        else:
            # If we can't find a page matching this slug or any
            # of its sub-slugs, skip all further processing.
            return None

        # Handle ``page.login_required``.
        if page.login_required and not request.user.is_authenticated():
            path = urlquote(request.get_full_path())
            bits = (settings.LOGIN_URL, REDIRECT_FIELD_NAME, path)
            return redirect("%s?%s=%s" % bits)

        if page.slug == slug and view_func == page_view:
            # Add the page to the ``extra_context`` arg for the
            # page view, which is responsible for choosing which
            # template to use, and raising 404 if there's no page
            # instance loaded.
            view_kwargs.setdefault("extra_context", {})
            view_kwargs["extra_context"]["page"] = page

        # We also first do wacky check with non-page views and 404s.
        # Basically if the view function isn't the page view and
        # raises a 404, but also matches an exact page slug, we then
        # forget about the non-page view, and run the page view
        # with the correct args.
        # This check allows us to set up pages with URLs that also
        # match non-page urlpatterns, for example a page could be
        # created with the URL /blog/about/, which would match the
        # blog urlpattern, and asusming there wasn't a blog post
        # with the slug "about", would raise a 404.
        try:
            response = view_func(request, *view_args, **view_kwargs)
        except Http404:
            if (page.slug == slug and view_func != page_view and
                    page.content_model != 'link'):
                # Matched a non-page urlpattern, but got a 404
                # for a URL that matches a valid page slug, so
                # use the page view.
                view_kwargs = {
                    "extra_context": {"page": page}
                }
                view_func = page_view
                response = view_func(request, slug, **view_kwargs)
            else:
                raise

        # If we can't add context to the response we just return it.
        # (redirects, etc)
        if getattr(response, "context_data", None) is None:
            return response

        # Add the page to its template context, and set helper
        # attributes like ``is_current``.
        response.context_data["page"] = page
        try:
            response.context_data["editable_obj"]
        except KeyError:
            response.context_data["editable_obj"] = page
        response.context_data["_current_page"] = page
        page.set_helpers(response.context_data)

        # Run page processors.
        model_processors = page_processors.processors[page.content_model]
        slug_processors = page_processors.processors["slug:%s" % page.slug]
        for (processor, exact_page) in slug_processors + model_processors:
            if exact_page and not page.is_current:
                continue
            processor_response = processor(request, page)
            if isinstance(processor_response, HttpResponse):
                return processor_response
            elif processor_response:
                try:
                    for k in processor_response:
                        if k not in response.context_data:
                            response.context_data[k] = processor_response[k]
                except (TypeError, ValueError):
                    name = "%s.%s" % (processor.__module__, processor.__name__)
                    error = ("The page processor %s returned %s but must "
                             "return HttpResponse or dict." %
                             (name, type(processor_response)))
                    raise ValueError(error)

        return response
Esempio n. 10
0
    def process_view(self, request, view_func, view_args, view_kwargs):
        """
        Per-request mechanics for the current page object.
        """

        cp = "mezzanine.pages.context_processors.page"
        if cp not in settings.TEMPLATE_CONTEXT_PROCESSORS:
            raise ImproperlyConfigured("%s is missing from "
                "settings.TEMPLATE_CONTEXT_PROCESSORS" % cp)

        # Load the closest matching page by slug, and assign it to the
        # request object. If none found, skip all further processing.
        slug = path_to_slug(request.path_info)
        pages = Page.objects.with_ascendants_for_slug(slug,
                        for_user=request.user, include_login_required=True)
        if pages:
            page = pages[0]
            setattr(request, "page", page)
        else:
            return

        # Handle ``page.login_required``.
        if page.login_required and not request.user.is_authenticated():
            path = urlquote(request.get_full_path())
            bits = (settings.LOGIN_URL, REDIRECT_FIELD_NAME, path)
            return redirect("%s?%s=%s" % bits)

        # Here we do a wacky check with non-page views and 404s.
        # Basically if the view function isn't the page view and
        # raises a 404, but also matches an exact page slug, we then
        # forget about the non-page view, and run the page view
        # with the correct args.
        # This check allows us to set up pages with URLs that also
        # match non-page urlpatterns, for example a page could be
        # created with the URL /blog/about/, which would match the
        # blog urlpattern, and assuming there wasn't a blog post
        # with the slug "about", would raise a 404.
        try:
            response = view_func(request, *view_args, **view_kwargs)
        except Http404:
            if (page.slug == slug and view_func != page_view and
                    page.content_model != 'link'):
                # Matched a non-page urlpattern, but got a 404
                # for a URL that matches a valid page slug, so
                # use the page view.
                response = page_view(request, slug, **view_kwargs)
            else:
                raise

        # Run page processors.
        model_processors = page_processors.processors[page.content_model]
        slug_processors = page_processors.processors["slug:%s" % page.slug]
        for (processor, exact_page) in slug_processors + model_processors:
            if exact_page and not page.is_current:
                continue
            processor_response = processor(request, page)
            if isinstance(processor_response, HttpResponse):
                return processor_response
            elif processor_response:
                try:
                    for k in processor_response:
                        if k not in response.context_data:
                            response.context_data[k] = processor_response[k]
                except (TypeError, ValueError):
                    name = "%s.%s" % (processor.__module__, processor.__name__)
                    error = ("The page processor %s returned %s but must "
                             "return HttpResponse or dict." %
                             (name, type(processor_response)))
                    raise ValueError(error)

        return response
    def process_view(self, request, view_func, view_args, view_kwargs):
        """
        Per-request mechanics for the current page object.
        """

        cp = "mezzanine.pages.context_processors.page"
        if cp not in settings.TEMPLATE_CONTEXT_PROCESSORS:
            raise ImproperlyConfigured("%s is missing from "
                                       "settings.TEMPLATE_CONTEXT_PROCESSORS" %
                                       cp)

        # Load the closest matching page by slug, and assign it to the
        # request object. If none found, skip all further processing.
        slug = path_to_slug(request.path_info)
        pages = Page.objects.with_ascendants_for_slug(
            slug, for_user=request.user, include_login_required=True)
        if pages:
            page = pages[0]
            setattr(request, "page", page)
        else:
            return

        # Handle ``page.login_required``.
        if page.login_required and not request.user.is_authenticated():
            path = urlquote(request.get_full_path())
            bits = (settings.LOGIN_URL, REDIRECT_FIELD_NAME, path)
            return redirect("%s?%s=%s" % bits)

        # Here we do a wacky check with non-page views and 404s.
        # Basically if the view function isn't the page view and
        # raises a 404, but also matches an exact page slug, we then
        # forget about the non-page view, and run the page view
        # with the correct args.
        # This check allows us to set up pages with URLs that also
        # match non-page urlpatterns, for example a page could be
        # created with the URL /blog/about/, which would match the
        # blog urlpattern, and assuming there wasn't a blog post
        # with the slug "about", would raise a 404.
        try:
            response = view_func(request, *view_args, **view_kwargs)
        except Http404:
            if (page.slug == slug and view_func != page_view
                    and page.content_model != 'link'):
                # Matched a non-page urlpattern, but got a 404
                # for a URL that matches a valid page slug, so
                # use the page view.
                response = page_view(request, slug, **view_kwargs)
            else:
                raise

        # Run page processors.
        model_processors = page_processors.processors[page.content_model]
        slug_processors = page_processors.processors["slug:%s" % page.slug]
        for (processor, exact_page) in slug_processors + model_processors:
            if exact_page and not page.is_current:
                continue
            processor_response = processor(request, page)
            if isinstance(processor_response, HttpResponse):
                return processor_response
            elif processor_response and hasattr(response, "context_data"):
                try:
                    for k in processor_response:
                        if k not in response.context_data:
                            response.context_data[k] = processor_response[k]
                except (TypeError, ValueError):
                    name = "%s.%s" % (processor.__module__, processor.__name__)
                    error = ("The page processor %s returned %s but must "
                             "return HttpResponse or dict." %
                             (name, type(processor_response)))
                    raise ValueError(error)

        return response
Esempio n. 12
0
    def process_view(self, request, view_func, view_args, view_kwargs):

        slug = path_to_slug(request.path_info)
        if slug == "/":
            slugs = [slug]
        else:
            # Create a list containing this slug, plus each of the
            # ascendant slugs: ['about', 'about/team', 'about/team/mike']
            parts = slug.split("/")
            slugs = ["/".join(parts[:i]) for i in range(1, len(parts) + 1)]

        pages_for_user = Page.objects.published(request.user)
        try:
            # Find the deepest page that matches one of our slugs.
            # Sorting by "-slug" ensures that the page with the
            # longest slug is selected if more than one page matches.
            page = pages_for_user.filter(slug__in=slugs).order_by("-slug")[0]
        except IndexError:
            # If we can't find a page matching this slug or any
            # of its sub-slugs, skip all further processing.
            return view_func(request, *view_args, **view_kwargs)

        # Handle ``page.login_required``.
        if page.login_required and not request.user.is_authenticated():
            path = urlquote(request.get_full_path())
            bits = (settings.LOGIN_URL, REDIRECT_FIELD_NAME, path)
            return redirect("%s?%s=%s" % bits)

        if page.slug == slug and view_func == page_view:
            # Add the page to the ``extra_context`` arg for the
            # page view, which is responsible for choosing which
            # template to use, and raising 404 if there's no page
            # instance loaded.
            view_kwargs.setdefault("extra_context", {})
            view_kwargs["extra_context"]["page"] = page

        # Create the response, and check that we can add context
        # to it. If not, it's something like a redirect, so we
        # just return it.
        response = view_func(request, *view_args, **view_kwargs)
        if not hasattr(response, "context_data"):
            return response

        # Add the page to its template context, and set helper
        # attributes like ``is_current``.
        response.context_data["page"] = page
        response.context_data["_current_page"] = page
        page.set_helpers(response.context_data)

        # Run page processors.
        model_processors = page_processors.processors[page.content_model]
        slug_processors = page_processors.processors["slug:%s" % page.slug]
        for (processor, exact_page) in model_processors + slug_processors:
            if exact_page and not page.is_current:
                continue
            processor_response = processor(request, page)
            if isinstance(processor_response, HttpResponse):
                return processor_response
            elif processor_response:
                try:
                    response.context_data.update(processor_response)
                except (TypeError, ValueError):
                    name = "%s.%s" % (processor.__module__, processor.__name__)
                    error = ("The page processor %s returned %s but must "
                             "return HttpResponse or dict." %
                             (name, type(processor_response)))
                    raise ValueError(error)

        return response
Esempio n. 13
0
def get_page(request):
    check_if_middleware_exists("mezzanine.pages")
    slug = path_to_slug(request.path_info)
    pages = page_service.get_page_ascendants(request, slug)
    return reduce(default_or_value, pages, "")