Adding custom URLs¶
Page types can provide custom URL patterns. These URL patterns are relative to the place where the page is added to the page tree.
This feature is useful for example to:
- Have a “Shop” page type where all products are sub pages.
- Have a “Blog” page type where all articles are displayed below.
To use this feature, provide a URLconf or an inline patterns()
list in the page type plugin.
Basic example¶
To have a plugin with custom views, add the urls
attribute:
@page_type_pool.register
class ProductCategoryPagePlugin(PageTypePlugin):
# ...
urls = patterns('myshop.views',
url('^(?P<slug>[^/]+)/$', 'product_details'),
)
The view is just a plain Django view:
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
from myshop.models import Product
def product_details(request, slug):
product = get_object_or_404(Product, slug=slug)
return render(request, 'products/product_details.html', {
'product': product
})
Other custom views can be created in the same way.
Resolving URLs¶
The URLs can’t be resolved using the standard reverse()
function unfortunately.
The main reason is that it caches results internally for the lifetime of the WSGI container,
meanwhile pages may be rearranged by the admin.
Hence, a app_reverse()
function is available.
It can be used to resolve the product page:
from fluent_pages.urlresolvers import app_reverse
app_reverse('product_details', kwargs={'slug': 'myproduct'})
In templates, there is an appurl
tag which accomplishes the same effect:
{% load appurl_tags %}
<a href="{% appurl 'product_details' slug='myproduct' %}">My Product</a>
See also
The example application in the source demonstrates this feature.
Compatibility with regular URLconf¶
An application can provide a standard urls.py
for regular Django support,
and still support page type URLs too. For this special case,
the mixed_reverse()
function is available.
It attemps to resolve the view in the standard URLconf first,
and falls back to app_reverse()
if the view is not found there.
A mixedurl
template tag has to be included in the application itself. Use the following code as example:
@register.tag
def mixedurl(parser, token):
if 'fluent_pages' in settings.INSTALLED_APPS:
from fluent_pages.templatetags.appurl_tags import appurl
return appurl(parser, token)
else:
from django.template.defaulttags import url
return url(parser, token)
See also
The django-fluent-blogs application uses this feature to optionally integrate the blog articles to the page tree.