diff --git a/doc/development/implementation/urlconfig.rst b/doc/development/implementation/urlconfig.rst
index 3d90e181b..b2bc7ebab 100644
--- a/doc/development/implementation/urlconfig.rst
+++ b/doc/development/implementation/urlconfig.rst
@@ -15,25 +15,33 @@ and the admin panel is available at ``https://pretix.eu/control/event/bigorg/awe
If the organizer now configures a custom domain like ``tickets.bigorg.com``, his event will
from now on be available on ``https://tickets.bigorg.com/awesomecon/``. The former URL at
-``pretix.eu`` will redirect there. However, the admin panel will still only be available
-on ``pretix.eu`` for convenience and security reasons.
+``pretix.eu`` will redirect there. It's also possible to do this for just an event, in which
+case the event will be available on ``https://tickets.awesomecon.org/``.
+
+However, the admin panel will still only be available on ``pretix.eu`` for convenience and security reasons.
URL routing
-----------
The hard part about implementing this URL routing in Django is that
``https://pretix.eu/bigorg/awesomecon/`` contains two parameters of nearly arbitrary content
-and ``https://tickets.bigorg.com/awesomecon/`` contains only one. The only robust way to do
-this is by having *separate* URL configuration for those two cases. In pretix, we call the
-former our ``maindomain`` config and the latter our ``subdomain`` config. For pretix's core
-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.
+and ``https://tickets.bigorg.com/awesomecon/`` contains only one and ``https://tickets.awesomecon.org/`` does not contain any.
+The only robust way to do this is by having *separate* URL configuration for those three cases.
+In pretix, we therefore do not have a global URL configuration, but three, living in the following modules:
+
+- ``pretix.multidomain.maindomain_urlconf``
+- ``pretix.multidomain.organizer_domain_urlconf``
+- ``pretix.multidomain.event_domain_urlconf``
+
+We provide some helper utilities to work with these to avoid duplicate configuration of the individual URLs.
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.
+However, unlike plain Django, we look not only for a ``urlpatterns`` attribute on the module but support other
+attributes like ``event_patterns`` and ``organizer_patterns`` as well.
-A very basic example that provides one view in the admin panel and one view in the frontend
-could look like this::
+For example, for a simple plugin that adds one URL to the backend and one event-level URL to the frontend, you can
+create the following configuration in your ``urls.py``::
from django.urls import re_path
@@ -52,7 +60,7 @@ could look like this::
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).
+ on the called domain). For organizer-level views, ``organizer_patterns`` works the same way.
If you only provide URLs in the admin area, you do not need to provide a ``event_patterns`` attribute.
@@ -71,11 +79,16 @@ is a python method that emulates a behavior similar to ``reverse``:
.. autofunction:: pretix.multidomain.urlreverse.eventreverse
+If you need to communicate the URL externally, you can use a different method to ensure that it is always an absolute URL:
+
+.. autofunction:: pretix.multidomain.urlreverse.build_absolute_uri
+
In addition, there is a template tag that works similar to ``url`` but takes an event or organizer object
as its first argument and can be used like this::
{% load eventurl %}
Pay
+ Pay
Implementation details
diff --git a/src/pretix/multidomain/urlreverse.py b/src/pretix/multidomain/urlreverse.py
index 5ce6e13b4..f764fc1f3 100644
--- a/src/pretix/multidomain/urlreverse.py
+++ b/src/pretix/multidomain/urlreverse.py
@@ -128,7 +128,7 @@ def eventreverse(obj, name, kwargs=None):
:param kwargs: A dictionary of additional keyword arguments that should be used. You do not
need to provide the organizer or event slug here, it will be added automatically as
needed.
- :returns: An absolute URL (including scheme and host) as a string
+ :returns: An absolute or relative URL as a string
"""
from pretix.multidomain import (
event_domain_urlconf, maindomain_urlconf, organizer_domain_urlconf,
@@ -177,6 +177,17 @@ def eventreverse(obj, name, kwargs=None):
def build_absolute_uri(obj, urlname, kwargs=None):
+ """
+ Works similar to ``eventreverse`` but always returns an absolute URL.
+
+ :param obj: An ``Event`` or ``Organizer`` object
+ :param name: The name of the URL route
+ :type name: str
+ :param kwargs: A dictionary of additional keyword arguments that should be used. You do not
+ need to provide the organizer or event slug here, it will be added automatically as
+ needed.
+ :returns: An absolute URL (including scheme and host) as a string
+ """
reversedurl = eventreverse(obj, urlname, kwargs)
if '://' in reversedurl:
return reversedurl