diff --git a/doc/development/api/plugins.rst b/doc/development/api/plugins.rst
index 181feadd7..fe2287eee 100644
--- a/doc/development/api/plugins.rst
+++ b/doc/development/api/plugins.rst
@@ -84,6 +84,8 @@ A working example would be:
restricted = False
description = _("This plugin allows you to receive payments via PayPal")
compatibility = "pretix>=2.7.0"
+ settings_links = []
+ navigation_links = []
default_app_config = 'pretix_paypal.PaypalApp'
@@ -185,6 +187,28 @@ your Django app label.
with checking that the calling user is logged in, has appropriate permissions,
etc. We plan on providing native support for this in a later version.
+To make your plugin views easily discoverable, you can specify links for "Go to"
+and "Settings" buttons next to your entry on the plugin page. These links should be
+added to the ``navigation_links`` and ``settings_links``, respectively, in the
+``PretixPluginMeta`` class.
+
+Each array entry consists of a tuple ``(label, urlname, kwargs)``. For the label,
+either a string or a tuple of strings can be specified. In the latter case, the provided
+strings will be merged with a separator indicating they are successive navigation steps
+the user would need to take to reach the page via the regular menu
+(e.g. "Payment > Bank transfer" as below).
+
+.. code-block:: python
+
+ settings_links = [
+ ((_("Payment"), _("Bank transfer")), "control:event.settings.payment.provider", {"provider": "banktransfer"}),
+ ]
+ navigation_links = [
+ ((_("Bank transfer"), _("Import bank data")), "plugins:banktransfer:import", {}),
+ ((_("Bank transfer"), _("Export refunds")), "plugins:banktransfer:refunds.list", {}),
+ ]
+
+
.. _Django app: https://docs.djangoproject.com/en/3.0/ref/applications/
.. _signal dispatcher: https://docs.djangoproject.com/en/3.0/topics/signals/
.. _namespace packages: https://legacy.python.org/dev/peps/pep-0420/
diff --git a/src/pretix/control/logdisplay.py b/src/pretix/control/logdisplay.py
index 6e1086021..7005579dc 100644
--- a/src/pretix/control/logdisplay.py
+++ b/src/pretix/control/logdisplay.py
@@ -43,7 +43,6 @@ from django.dispatch import receiver
from django.urls import reverse
from django.utils.formats import date_format
from django.utils.html import escape, format_html
-from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _, pgettext_lazy
from i18nfield.strings import LazyI18nString
@@ -286,7 +285,7 @@ class OrderChangedSplit(OrderChangeLogEntryType):
_('Position #{posid} ({old_item}, {old_price}) split into new order: {order}'),
old_item=escape(old_item),
posid=data.get('positionid', '?'),
- order=format_html(mark_safe('{}'), url, data['new_order']),
+ order=format_html('{}', url, data['new_order']),
old_price=money_filter(Decimal(data['old_price']), event.currency),
)
@@ -303,7 +302,7 @@ class OrderChangedSplitFrom(OrderLogEntryType):
})
return format_html(
_('This order has been created by splitting the order {order}'),
- order=format_html(mark_safe('{}'), url, data['original_order']),
+ order=format_html('{}', url, data['original_order']),
)
diff --git a/src/pretix/control/navigation.py b/src/pretix/control/navigation.py
index c081961aa..bfd5aef7c 100644
--- a/src/pretix/control/navigation.py
+++ b/src/pretix/control/navigation.py
@@ -59,7 +59,7 @@ def get_event_navigation(request: HttpRequest):
'event': request.event.slug,
'organizer': request.event.organizer.slug,
}),
- 'active': url.url_name == 'event.settings.payment',
+ 'active': url.url_name in ('event.settings.payment', 'event.settings.payment.provider'),
},
{
'label': _('Plugins'),
diff --git a/src/pretix/control/templates/pretixcontrol/event/fragment_plugin_description.html b/src/pretix/control/templates/pretixcontrol/event/fragment_plugin_description.html
index 588e87276..fa370d7c1 100644
--- a/src/pretix/control/templates/pretixcontrol/event/fragment_plugin_description.html
+++ b/src/pretix/control/templates/pretixcontrol/event/fragment_plugin_description.html
@@ -7,7 +7,7 @@
{% endblocktrans %}
{% endif %}
{% endif %}
-
{{ plugin.description|safe }}
+
{{ plugin.description|safe }}
{% if plugin.restricted and plugin.module not in request.event.settings.allowed_restricted_plugins %}
+
{% url "control:event.settings.plugins" event=request.event.slug organizer=request.organizer.slug as plugin_settings_url %}
- {% blocktrans trimmed with plugin_settings_href='href="'|add:plugin_settings_url|add:'"'|safe %}
- There are no payment providers available. Please go to the
- plugin settings and activate one or more payment plugins.
- {% endblocktrans %}
+
+ {% trans "Enable additional payment plugins" %}
+