Simplify the API for custom URLs

This commit is contained in:
Raphael Michel
2016-07-31 13:04:17 +02:00
parent 3a96ec78f0
commit c744ee93b9
5 changed files with 34 additions and 35 deletions

View File

@@ -12,7 +12,7 @@ Control panel views
-------------------
If you want to add a custom view to the control area of an event, just register an URL in your
``maindomain_urls.py`` that lives in the ``/control/`` subpath::
``urls.py`` that lives in the ``/control/`` subpath::
from django.conf.urls import url
@@ -66,26 +66,14 @@ Frontend views
Including a custom view into the participant-facing frontend is a little bit different as there is
no path prefix like ``control/``.
First, define your URL in your ``maindomain_urls.py``::
First, define your URL in your ``urls.py``, but this time in the ``event_patterns`` section::
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^(?P<organizer>[^/]+)/(?P<event>[^/]+)/mypluginname/',
views.frontend_view, name='frontend'),
]
And for the case of custom domains in your ``subdomain_urls.py``::
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^(?P<event>[^/]+)/mypluginname/',
views.frontend_view, name='frontend'),
event_patterns = [
url(r'^mypluginname/', views.frontend_view, name='frontend'),
]
You can then implement a view as you would normally do, but you need to apply a decorator to your
@@ -104,4 +92,4 @@ correctly ensure that:
* The event is accessed via the domain it should be accessed
* The ``request.event`` attribute contains the correct ``Event`` object
* The ``request.organizer`` attribute contains the correct ``Organizer`` object
* The locale is set correctly
* The locale is set correctly

View File

@@ -29,8 +29,8 @@ former our ``maindomain`` config and the latter our ``subdomain`` config. For pr
modules we do some magic to avoid duplicate configuration, but for a fairly simple plugin with
only a handful of routes, we recommend just configuring the two URL sets separately.
The file ``maindomain_urls.py`` inside your plugin package will be loaded and scanned for
URL configuration automatically and should be provided by any plugin that provides any view.
The file ``urls.py`` inside your plugin package will be loaded and scanned for URL configuration
automatically and should be provided by any plugin that provides any view.
A very basic example that provides one view in the admin panel and one view in the frontend
could look like this::
@@ -42,23 +42,19 @@ could look like this::
urlpatterns = [
url(r'^control/event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/mypluginname/',
views.AdminView.as_view(), name='backend'),
url(r'^(?P<organizer>[^/]+)/(?P<event>[^/]+)/mypluginname/',
views.FrontendView.as_view(), name='frontend'),
]
A matching configuration for custom domains will be expected in the ``subdomain_urls.py`` file
of your package and would look like this::
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^(?P<event>[^/]+)/mypluginname/',
views.FrontendView.as_view(), name='frontend'),
event_patterns = [
url(r'^mypluginname/', views.FrontendView.as_view(), name='frontend'),
]
If you only provide URLs in the admin area, you do not need to provide a ``subdomain_urls`` module.
.. note::
As you can see, the view in the frontend is not included in the standard Django ``urlpatterns``
setting but in a separate list with the name ``event_patterns``. This will automatically prepend
the appropriate parameters to the regex (e.g. the event or the event and the organizer, depending
on the called domain).
If you only provide URLs in the admin area, you do not need to provide a ``event_patterns`` attribute.
URL reversal
------------

View File

@@ -20,7 +20,16 @@ presale_patterns_main = [
raw_plugin_patterns = []
for app in apps.get_app_configs():
if hasattr(app, 'PretixPluginMeta'):
if importlib.util.find_spec(app.name + '.maindomain_urls'):
if importlib.util.find_spec(app.name + '.urls'):
urlmod = importlib.import_module(app.name + '.urls')
raw_plugin_patterns.append(
url(r'', include(urlmod, namespace=app.label))
)
if hasattr(urlmod, 'event_patterns'):
raw_plugin_patterns.append(
url(r'^(?P<organizer>[^/]+)/(?P<event>[^/]+)/', include(urlmod.event_patterns, namespace=app.label))
)
elif importlib.util.find_spec(app.name + '.maindomain_urls'):
urlmod = importlib.import_module(app.name + '.maindomain_urls')
raw_plugin_patterns.append(
url(r'', include(urlmod, namespace=app.label))

View File

@@ -19,7 +19,13 @@ presale_patterns = [
raw_plugin_patterns = []
for app in apps.get_app_configs():
if hasattr(app, 'PretixPluginMeta'):
if importlib.util.find_spec(app.name + '.subdomain_urls'):
if importlib.util.find_spec(app.name + '.urls'):
urlmod = importlib.import_module(app.name + '.urls')
if hasattr(urlmod, 'event_patterns'):
raw_plugin_patterns.append(
url(r'^(?P<event>[^/]+)/', include(urlmod.event_patterns, namespace=app.label))
)
elif importlib.util.find_spec(app.name + '.subdomain_urls'):
urlmod = importlib.import_module(app.name + '.subdomain_urls')
raw_plugin_patterns.append(
url(r'', include(urlmod, namespace=app.label))

View File

@@ -47,7 +47,7 @@ def eventurl(parser, token):
"""
bits = token.split_contents()
if len(bits) < 3:
raise TemplateSyntaxError("'%s' takes at least one argument, an event and the name of a url()." % bits[0])
raise TemplateSyntaxError("'%s' takes at least two arguments, an event and the name of a url()." % bits[0])
viewname = parser.compile_filter(bits[2])
event = parser.compile_filter(bits[1])
kwargs = {}