示例#1
0
    def test_app_reverse_multiple(self):
        """
        The app_reverse functions should support multiple mount points for an app.
        """
        shop2 = WebShopPage.objects.create(title="Shop2",
                                           slug="shop2",
                                           status=WebShopPage.PUBLISHED,
                                           author=self.user)
        self.assertEqual(WebShopPage.objects.published().count(), 2)

        # There are now 2 mount points, the functions should detect that
        self.assertRaises(MultipleReverseMatch,
                          lambda: app_reverse('webshop_index'))
        self.assertRaises(MultipleReverseMatch,
                          lambda: mixed_reverse('webshop_index'))

        # The functions have a 'current_page' parameter that allows relative resolving.
        # This is designed for template functions, to allow resolving relative to the current page node.
        self.assertEqual(app_reverse('webshop_index', current_page=shop2),
                         '/shop2/')
        self.assertEqual(
            app_reverse('webshop_article',
                        current_page=shop2,
                        kwargs={'slug': 'foobar'}), '/shop2/foobar/')

        self.assertEqual(mixed_reverse('webshop_index', current_page=shop2),
                         '/shop2/')
        self.assertEqual(
            mixed_reverse('webshop_article',
                          current_page=shop2,
                          kwargs={'slug': 'foobar'}), '/shop2/foobar/')
示例#2
0
 def test_mixed_reverse_standalone(self):
     """
     When a custom app is not hooked via the CMS page tree, mixed_reverse() should still work.
     """
     self.assertRaises(PageTypeNotMounted, lambda: app_reverse('webshop_index'))
     self.assertEqual(mixed_reverse('webshop_index'), '/')
     self.assertEqual(mixed_reverse('webshop_article', kwargs={'slug': 'foobar'}), '/foobar/')
示例#3
0
 def test_mixed_reverse_standalone(self):
     """
     When a custom app is not hooked via the CMS page tree, mixed_reverse() should still work.
     """
     self.assertRaises(PageTypeNotMounted, lambda: app_reverse('webshop_index'))
     self.assertEqual(mixed_reverse('webshop_index'), '/')
     self.assertEqual(mixed_reverse('webshop_article', kwargs={'slug': 'foobar'}), '/foobar/')
示例#4
0
    def test_app_reverse(self):
        """
        The app_reverse function should find the proper CMS page where the app is mounted.
        """
        self.assertEqual(app_reverse('webshop_index'), '/shop/')
        self.assertEqual(app_reverse('webshop_article', kwargs={'slug': 'foobar'}), '/shop/foobar/')

        self.assertEqual(mixed_reverse('webshop_index'), '/shop/')
        self.assertEqual(mixed_reverse('webshop_article', kwargs={'slug': 'foobar'}), '/shop/foobar/')
示例#5
0
    def test_app_reverse(self):
        """
        The app_reverse function should find the proper CMS page where the app is mounted.
        """
        self.assertEqual(WebShopPage.objects.published().count(), 1)

        self.assertEqual(app_reverse('webshop_index'), '/shop/')
        self.assertEqual(app_reverse('webshop_article', kwargs={'slug': 'foobar'}), '/shop/foobar/')

        self.assertEqual(mixed_reverse('webshop_index'), '/shop/')
        self.assertEqual(mixed_reverse('webshop_article', kwargs={'slug': 'foobar'}), '/shop/foobar/')
    def get_value(self, context, *tag_args, **tag_kwargs):
        view_name = tag_args[0]
        url_args = tag_args[1::]
        url_kwargs = dict([(smart_str(name, 'ascii'), value) for name, value in iteritems(tag_kwargs)])

        # The app_reverse() tag can handle multiple results fine if it knows what the current page is.
        # Try to find it.
        request = context.get('request')
        page = getattr(request, '_current_fluent_page', None)
        if not page:
            # There might be a 'page' variable, that was retrieved via `{% get_fluent_page_vars %}`.
            # However, django-haystack also uses this variable name, so check whether it's the correct object.
            page = context.get('page')
            if not isinstance(page, UrlNode):
                page = None

        if django.VERSION >= (1, 8):
            # request.current_app is passed everywhere if available, otherwise it does not exist.
            # Somehow it needs to be assigned explicitly in the app
            # via: request.current_app = request.resolver_match.namespace
            current_app = getattr(request, 'current_app', None)
        else:
            current_app = context.current_app

        # Try a normal URLConf URL, then an app URL
        return mixed_reverse(view_name, args=url_args, kwargs=url_kwargs, current_app=current_app, current_page=page)
示例#7
0
    def get_value(self, context, *tag_args, **tag_kwargs):
        view_name = tag_args[0]
        url_args = tag_args[1::]
        url_kwargs = dict([(smart_str(name, 'ascii'), value)
                           for name, value in iteritems(tag_kwargs)])

        # The app_reverse() tag can handle multiple results fine if it knows what the current page is.
        # Try to find it.
        request = context.get('request')
        page = getattr(request, '_current_fluent_page', None)
        if not page:
            # There might be a 'page' variable, that was retrieved via `{% get_fluent_page_vars %}`.
            # However, django-haystack also uses this variable name, so check whether it's the correct object.
            page = context.get('page')
            if not isinstance(page, UrlNode):
                page = None

        # request.current_app is passed everywhere if available, otherwise it does not exist.
        # Somehow it needs to be assigned explicitly in the app
        # via: request.current_app = request.resolver_match.namespace
        current_app = getattr(request, 'current_app', None)

        # Try a normal URLConf URL, then an app URL
        return mixed_reverse(view_name,
                             args=url_args,
                             kwargs=url_kwargs,
                             current_app=current_app,
                             current_page=page)
示例#8
0
def faq_reverse(viewname,
                args=None,
                kwargs=None,
                current_app='fluent_faq',
                current_page=None,
                language_code=None,
                multiple=False,
                ignore_multiple=False):
    """
    Reverse a URL to the blog, taking various configuration options into account.

    This is a compatibility function to allow django-fluent-faq to operate stand-alone.
    Either the app can be hooked in the URLconf directly, or it can be added as a pagetype of *django-fluent-pages*.
    """
    if _HAS_FLUENT_PAGES:
        return mixed_reverse(viewname,
                             args=args,
                             kwargs=kwargs,
                             current_page=current_page,
                             language_code=language_code,
                             multiple=multiple,
                             ignore_multiple=ignore_multiple)
    else:
        return reverse(viewname,
                       args=args,
                       kwargs=kwargs,
                       current_app=current_app)
def blog_reverse(
    viewname,
    args=None,
    kwargs=None,
    current_app="fluent_blogs",
    current_page=None,
    multiple=False,
    ignore_multiple=False,
):
    """
    Reverse a URL to the blog, taking various configuration options into account.

    This is a compatibility function to allow django-fluent-blogs to operate stand-alone.
    Either the app can be hooked in the URLconf directly, or it can be added as a pagetype of *django-fluent-pages*.
    """
    if _HAS_FLUENT_PAGES:
        return mixed_reverse(
            viewname,
            args=args,
            kwargs=kwargs,
            current_page=current_page,
            multiple=multiple,
            ignore_multiple=ignore_multiple,
        )
    else:
        return reverse(viewname, args=args, kwargs=kwargs, current_app=current_app)
示例#10
0
 def test_app_reverse_unmounted(self):
     """
     The app_reverse functions should raise an exception when the pagetype is not added in the page tree.
     """
     for page in WebShopPage.objects.all():
         page.delete()  # Allow signals to be sent, and clear caches
     self.assertRaises(PageTypeNotMounted, lambda: app_reverse('webshop_index'))
     self.assertRaises(PageTypeNotMounted, lambda: mixed_reverse('webshop_index'))
示例#11
0
    def test_app_reverse_multiple(self):
        """
        The app_reverse functions should support multiple mount points for an app.
        """
        shop2 = WebShopPage.objects.create(title="Shop2", slug="shop2", status=WebShopPage.PUBLISHED, author=self.user)

        # There are now 2 mount points, the functions should detect that
        self.assertRaises(MultipleReverseMatch, lambda: app_reverse('webshop_index'))
        self.assertRaises(MultipleReverseMatch, lambda: mixed_reverse('webshop_index'))

        # The functions have a 'current_page' parameter that allows relative resolving.
        # This is designed for template functions, to allow resolving relative to the current page node.
        self.assertEqual(app_reverse('webshop_index', current_page=shop2), '/shop2/')
        self.assertEqual(app_reverse('webshop_article', current_page=shop2, kwargs={'slug': 'foobar'}), '/shop2/foobar/')

        self.assertEqual(mixed_reverse('webshop_index', current_page=shop2), '/shop2/')
        self.assertEqual(mixed_reverse('webshop_article', current_page=shop2, kwargs={'slug': 'foobar'}), '/shop2/foobar/')
示例#12
0
 def test_app_reverse_unmounted(self):
     """
     The app_reverse functions should raise an exception when the pagetype is not added in the page tree.
     """
     for page in WebShopPage.objects.all():
         page.delete()  # Allow signals to be sent, and clear caches
     self.assertEqual(WebShopPage.objects.published().count(), 0)
     self.assertRaises(PageTypeNotMounted, lambda: app_reverse('webshop_index'))
     self.assertRaises(PageTypeNotMounted, lambda: mixed_reverse('webshop_index'))
    def render_tag(self, context, *tag_args, **tag_kwargs):
        view_name = tag_args[0]
        url_args = tag_args[1::]
        url_kwargs = dict([(smart_str(name, 'ascii'), value) for name, value in tag_kwargs.items()])

        # If the page is a UrlNode, use it as base for the pages.
        page = context.get('page')
        if not isinstance(page, UrlNode):
            page = None

        # Try a normal URLConf URL, then an app URL
        return mixed_reverse(view_name, args=url_args, kwargs=url_kwargs, current_app=context.current_app, current_page=page)
示例#14
0
    def get_view_url(self):
        """
        When using the :attr:`ViewUrlMixin.view_url_name <parler.views.ViewUrlMixin.view_url_name>` feature of *django-parler*,
        this makes sure that mounted pages are also supported.

        It uses :func:`fluent_pages.urlresolvers.mixed_reverse` function to resolve the :attr:`view_url_name`.
        """
        # This method is used by the ``get_translated_url`` template tag of django-parler
        if self.view_url_name:
            return mixed_reverse(self.view_url_name, args=self.args, kwargs=self.kwargs, current_page=self.get_current_page())
        else:
            return super(CurrentPageMixin, self).get_view_url()
示例#15
0
    def render(self, context):
        # If the page is a UrlNode, use it as base for the pages.
        page = context['page']
        if not isinstance(page, UrlNode):
            page = None

        view_name = self.name_expr.resolve(context)
        args = [arg.resolve(context) for arg in self.args]
        kwargs = dict([(smart_str(k, 'ascii'), v.resolve(context)) for k, v in self.kwargs.items()])

        # Try a normal URLConf URL, then an app URL
        return mixed_reverse(view_name, args=args, kwargs=kwargs, current_app=context.current_app, current_page=page)
示例#16
0
    def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
        # When the page is accessed via a pagetype, warn that the node can't be previewed yet.
        context['preview_error'] = ''
        if 'fluent_pages' in settings.INSTALLED_APPS:
            from fluent_pages.urlresolvers import mixed_reverse, PageTypeNotMounted, MultipleReverseMatch
            try:
                mixed_reverse('entry_archive_index')
            except PageTypeNotMounted:
                from fluent_blogs.pagetypes.blogpage.models import BlogPage
                context['preview_error'] = ugettext("The blog entry can't be previewed yet, a '{page_type_name}' page needs to be created first.").format(page_type_name=BlogPage._meta.verbose_name)
            except MultipleReverseMatch:
                # When 'entry_archive_index is ambiguous (because there are multiple blog nodes in the fluent-pages tree),
                # the edit page will automatically pick an option.
                pass
            except NoReverseMatch:
                # Since forgetting the pagetype app is easy, give off a warning to help developers
                # find their way with these apps.
                raise ImproperlyConfigured(
                    "To use django-fluent-blogs, either include('fluent_blogs.urls') in the URLConf, "
                    "or add the 'fluent_blogs.pagetypes.blogpage' app to the INSTALLED_APPS."
                )

        return super(AbstractEntryBaseAdmin, self).render_change_form(request, context, add, change, form_url, obj)
示例#17
0
    def render(self, context):
        # If the page is a UrlNode, use it as base for the pages.
        page = context['page']
        if not isinstance(page, UrlNode):
            page = None

        view_name = self.name_expr.resolve(context)
        args = [arg.resolve(context) for arg in self.args]
        kwargs = dict([(smart_str(k, 'ascii'), v.resolve(context))
                       for k, v in self.kwargs.items()])

        # Try a normal URLConf URL, then an app URL
        return mixed_reverse(view_name,
                             args=args,
                             kwargs=kwargs,
                             current_app=context.current_app,
                             current_page=page)
示例#18
0
    def render_tag(self, context, *tag_args, **tag_kwargs):
        view_name = tag_args[0]
        url_args = tag_args[1::]
        url_kwargs = dict([(smart_str(name, 'ascii'), value)
                           for name, value in tag_kwargs.items()])

        # If the page is a UrlNode, use it as base for the pages.
        page = context.get('page')
        if not isinstance(page, UrlNode):
            page = None

        # Try a normal URLConf URL, then an app URL
        return mixed_reverse(view_name,
                             args=url_args,
                             kwargs=url_kwargs,
                             current_app=context.current_app,
                             current_page=page)
    def render_tag(self, context, *tag_args, **tag_kwargs):
        view_name = tag_args[0]
        url_args = tag_args[1::]
        url_kwargs = dict([(smart_str(name, 'ascii'), value) for name, value in iter(tag_kwargs.items())])

        # The app_reverse() tag can handle multiple results fine if it knows what the current page is.
        # Try to find it.
        request = context.get('request')
        page = getattr(request, '_current_fluent_page', None)
        if not page:
            # There might be a 'page' variable, that was retrieved via `{% get_fluent_page_vars %}`.
            # However, django-haystack also uses this variable name, so check whether it's the correct object.
            page = context.get('page')
            if not isinstance(page, UrlNode):
                page = None

        # Try a normal URLConf URL, then an app URL
        return mixed_reverse(view_name, args=url_args, kwargs=url_kwargs, current_app=context.current_app, current_page=page)
示例#20
0
    def render_tag(self, context, *tag_args, **tag_kwargs):
        view_name = tag_args[0]
        url_args = tag_args[1::]
        url_kwargs = dict([(smart_str(name, 'ascii'), value) for name, value in iteritems(tag_kwargs)])

        # The app_reverse() tag can handle multiple results fine if it knows what the current page is.
        # Try to find it.
        request = context.get('request')
        page = getattr(request, '_current_fluent_page', None)
        if not page:
            # There might be a 'page' variable, that was retrieved via `{% get_fluent_page_vars %}`.
            # However, django-haystack also uses this variable name, so check whether it's the correct object.
            page = context.get('page')
            if not isinstance(page, UrlNode):
                page = None

        # Try a normal URLConf URL, then an app URL
        return mixed_reverse(view_name, args=url_args, kwargs=url_kwargs, current_app=context.current_app, current_page=page)
 def _reverse_blogpage_index(self, request, obj=None):
     # Updated mixed_reverse() call, with language code included.
     from fluent_pages.urlresolvers import mixed_reverse
     language_code = self.get_form_language(request, obj)
     return mixed_reverse('entry_archive_index', language_code=language_code)
示例#22
0
 def _reverse_blogpage_index(self, request, obj=None):
     # Updated mixed_reverse() call, with language code included.
     from fluent_pages.urlresolvers import mixed_reverse
     language_code = self.get_form_language(request, obj)
     return mixed_reverse('entry_archive_index',
                          language_code=language_code)
示例#23
0
 def _reverse_blogpage_index(self, request, obj=None):
     # Internal method with "protected access" to handle translation differences.
     # This is only called when 'fluent_pages' is in the INSTALLED_APPS.
     from fluent_pages.urlresolvers import mixed_reverse
     return mixed_reverse('entry_archive_index')
示例#24
0
 def _reverse_faqpage_index(self, request, obj=None):
     # Internal method with "protected access" to handle translation differences.
     # This is only called when 'fluent_pages' is in the INSTALLED_APPS.
     from fluent_pages.urlresolvers import mixed_reverse
     return mixed_reverse('faqquestion_index')