diff --git a/src/pretix/base/templatetags/anonymize_email.py b/src/pretix/base/templatetags/anonymize_email.py
new file mode 100644
index 000000000..b1e75b100
--- /dev/null
+++ b/src/pretix/base/templatetags/anonymize_email.py
@@ -0,0 +1,13 @@
+from django import template
+from django.utils.html import mark_safe
+
+register = template.Library()
+
+
+@register.filter("anon_email")
+def anon_email(value):
+ """Replaces @ with [at] and . with [dot] for anonymization."""
+ if not isinstance(value, str):
+ return value
+ value = value.replace("@", "[at]").replace(".", "[dot]")
+ return mark_safe(''.join(['{0};'.format(ord(char)) for char in value]))
diff --git a/src/pretix/presale/templates/pretixpresale/event/base.html b/src/pretix/presale/templates/pretixpresale/event/base.html
index 99422e54c..984410d3b 100644
--- a/src/pretix/presale/templates/pretixpresale/event/base.html
+++ b/src/pretix/presale/templates/pretixpresale/event/base.html
@@ -6,6 +6,7 @@
{% load eventurl %}
{% load safelink %}
{% load rich_text %}
+{% load anonymize_email %}
{% block thetitle %}
{% if messages %}
{{ messages|join:" " }} ::
@@ -219,7 +220,7 @@
{% endblock %}
{% block footernav %}
{% if request.event.settings.contact_mail %}
-
{% trans "Contact" %}
+ {% trans "Contact" %}
{% endif %}
{% if request.event.settings.privacy_url %}
{% trans "Privacy policy" %}
diff --git a/src/pretix/presale/templates/pretixpresale/fragment_js.html b/src/pretix/presale/templates/pretixpresale/fragment_js.html
index 09350e862..37ca39ed1 100644
--- a/src/pretix/presale/templates/pretixpresale/fragment_js.html
+++ b/src/pretix/presale/templates/pretixpresale/fragment_js.html
@@ -21,4 +21,5 @@
+
{% endcompress %}
diff --git a/src/pretix/presale/templates/pretixpresale/organizers/base.html b/src/pretix/presale/templates/pretixpresale/organizers/base.html
index 1783b758f..da77df7cd 100644
--- a/src/pretix/presale/templates/pretixpresale/organizers/base.html
+++ b/src/pretix/presale/templates/pretixpresale/organizers/base.html
@@ -5,6 +5,7 @@
{% load thumb %}
{% load eventurl %}
{% load safelink %}
+{% load anonymize_email %}
{% block thetitle %}
{% block title %}{% endblock %}{% if url_name != "organizer.index" %} :: {% endif %}{{ organizer.name }}
{% endblock %}
@@ -97,7 +98,7 @@
{% endblock %}
{% block footernav %}
{% if not request.event and request.organizer.settings.contact_mail %}
- {% trans "Contact" %}
+ {% trans "Contact" %}
{% endif %}
{% if not request.event and request.organizer.settings.privacy_url %}
{% trans "Privacy policy" %}
diff --git a/src/pretix/static/pretixbase/js/deanonymize_email.js b/src/pretix/static/pretixbase/js/deanonymize_email.js
new file mode 100644
index 000000000..d01035ee6
--- /dev/null
+++ b/src/pretix/static/pretixbase/js/deanonymize_email.js
@@ -0,0 +1,7 @@
+document.addEventListener('DOMContentLoaded', function() {
+ document.querySelectorAll('a[href^="mailto:"]').forEach(function(link) {
+ // Replace [at] with @ and the [dot] with . in both the href and the displayed text (if needed)
+ link.href = link.href.replace('[at]', '@').replace('[dot]', '.');
+ link.textContent = link.textContent.replace('[at]', '@').replace('[dot]', '.');
+ });
+});