Skip to content

Commit aba2751

Browse files
sneridaghdavisagliTishasoumya-02iFlameing
authored
Add backend for DSVGO banner settings (#39)
* Add backend for DSVGO banner settings * Fix locales * changelog * fix i18n domain * lint * use 'dsgvo-setting-for-ttw' for dsgvo banner * fix translations, make sure we use the right settings * update the dsgvo version * update lockfile * update VLT * update volto * Add tracker, tracker options and privacy URL fields to the DSGVO control panel. * add changelog * fix format * delete settings coming from dsgvo and add docs * update the widget for privacy_url to support multilingual website * update dsgvo banner branch * add changelog * update the package versions --------- Co-authored-by: David Glick <david@glicksoftware.com> Co-authored-by: Tishasoumya-02 <tishasoumya@gmail.com> Co-authored-by: iFlameing <ialokkumarsingh0@gmail.com>
1 parent e57f501 commit aba2751

28 files changed

Lines changed: 626 additions & 269 deletions

backend/news/+dsgvo.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add control panel for GDPR / DSGVO settings. @davisagli
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add tracker, tracker options and privacy URL fields to the DSGVO control panel. @iFlameing

backend/pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ lint.select = [
179179
lint.ignore = [
180180
# DoNotAssignLambda
181181
"E731",
182+
# https://docs.astral.sh/ruff/rules/suppressible-exception/
183+
"SIM105",
182184
]
183185

184186
[tool.ruff.lint.isort]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
11
<configure xmlns="http://namespaces.zope.org/zope">
22

3+
<adapter
4+
factory=".dsgvo.DSGVOControlpanel"
5+
name="dsgvo-settings"
6+
/>
7+
<adapter
8+
factory=".dsgvo.DSGVOSiteEndpointExpander"
9+
name="kitconcept.website.dsgvo"
10+
/>
11+
312
</configure>
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
from kitconcept.website import _
2+
from kitconcept.website.interfaces import IBrowserLayer
3+
from plone.autoform import directives
4+
from plone.registry.interfaces import IRegistry
5+
from plone.restapi.controlpanels import RegistryConfigletPanel
6+
from plone.restapi.interfaces import ISiteEndpointExpander
7+
from plone.schema import JSONField
8+
from zope import schema
9+
from zope.component import adapter
10+
from zope.component import getUtility
11+
from zope.interface import Interface
12+
from zope.interface import implementer
13+
from zope.schema.vocabulary import SimpleVocabulary
14+
15+
import json
16+
17+
18+
# These are the modules supported in
19+
# https://github.com/kitconcept/volto-dsgvo-banner/blob/main/packages/volto-dsgvo-banner/src/components/Block/View.jsx
20+
DSGVO_MODULES = SimpleVocabulary.fromValues([
21+
"tracking",
22+
"youtube",
23+
"facebook",
24+
"google",
25+
"vimeo",
26+
"twitter",
27+
])
28+
29+
DSGVO_TRACKERS = SimpleVocabulary.fromValues(["google", "matomo"])
30+
31+
TRACKER_OPTIONS_SCHEMA = json.dumps({
32+
"type": "object",
33+
})
34+
35+
PRIVACY_URL_SCHEMA = json.dumps({
36+
"type": "object",
37+
})
38+
39+
40+
class IDSGVOSettings(Interface):
41+
"""Settings for @kitconcept/volto-dsgvo-banner"""
42+
43+
show_banner = schema.Bool(
44+
title=_("label_dsgvo_show_banner", default="Show GDPR banner on first visit"),
45+
description=_(
46+
"help_dsgvo_show_banner",
47+
default="If true, the cookie consent banner will be shown immediately. "
48+
"If false, users will be prompted to accept cookies only in the context "
49+
"of blocks where they are needed.",
50+
),
51+
default=True,
52+
)
53+
54+
modules = schema.List(
55+
title=_("label_dsgvo_modules", default="Show privacy settings for"),
56+
description=_(
57+
"help_dsgvo_modules",
58+
default="List of 3rd-party sites to be shown in privacy preferences.",
59+
),
60+
value_type=schema.Choice(
61+
vocabulary=DSGVO_MODULES,
62+
),
63+
default=["tracking", "youtube", "facebook", "google"],
64+
required=True,
65+
)
66+
67+
tracker = schema.Choice(
68+
title=_("label_dsgvo_tracker", default="Tracker"),
69+
description=_(
70+
"help_dsgvo_tracker",
71+
default="Analytics tracker to use. Choose 'google' for Google Analytics "
72+
"or 'matomo' for Matomo.",
73+
),
74+
vocabulary=DSGVO_TRACKERS,
75+
required=False,
76+
default=None,
77+
)
78+
79+
directives.widget(
80+
"tracker_options",
81+
frontendOptions={
82+
"widget": "modalJSONEditor",
83+
},
84+
)
85+
tracker_options = JSONField(
86+
title=_("label_dsgvo_tracker_options", default="Tracker options"),
87+
description=_(
88+
"help_dsgvo_tracker_options",
89+
default="JSON object with tracker configuration. "
90+
'For Google Analytics: {"id": "G-XXXXXXX", "gaOptions": {"anonymizeIp": true}}. '
91+
'For Matomo: {"id": 1, "urlBase": "https://matomo.example.com/"}.',
92+
),
93+
schema=TRACKER_OPTIONS_SCHEMA,
94+
required=False,
95+
default=None,
96+
missing_value=None,
97+
widget="",
98+
)
99+
100+
directives.widget(
101+
"privacy_url",
102+
frontendOptions={
103+
"widget": "modalJSONEditor",
104+
},
105+
)
106+
privacy_url = JSONField(
107+
title=_("label_dsgvo_privacy_url", default="Privacy policy URL"),
108+
description=_(
109+
"help_dsgvo_privacy_url",
110+
default="JSON object mapping language codes to privacy policy paths or URLs. "
111+
'Example: {"en": "/en/privacy", "de": "/de/datenschutz"}.',
112+
),
113+
schema=PRIVACY_URL_SCHEMA,
114+
required=False,
115+
default=None,
116+
missing_value=None,
117+
widget="",
118+
)
119+
120+
121+
@adapter(Interface, Interface)
122+
class DSGVOControlpanel(RegistryConfigletPanel):
123+
"""REST API control panel for DSGVO settings."""
124+
125+
schema = IDSGVOSettings
126+
configlet_id = "dsgvo-settings"
127+
configlet_category_id = "plone-general"
128+
schema_prefix = "kitconcept.website.dsgvo"
129+
130+
131+
@adapter(Interface, IBrowserLayer)
132+
@implementer(ISiteEndpointExpander)
133+
class DSGVOSiteEndpointExpander:
134+
"""Add DSGVO settings to the @site endpoint."""
135+
136+
def __init__(self, context, request):
137+
self.context = context
138+
self.request = request
139+
140+
def __call__(self, data):
141+
registry = getUtility(IRegistry)
142+
settings = registry.forInterface(
143+
IDSGVOSettings, prefix="kitconcept.website.dsgvo", check=False
144+
)
145+
try:
146+
data["kitconcept.website.dsgvo"] = {
147+
"show_banner": settings.show_banner,
148+
"modules": settings.modules,
149+
"tracker": settings.tracker,
150+
"tracker_options": settings.tracker_options,
151+
"privacy_url": settings.privacy_url,
152+
}
153+
except AttributeError:
154+
# Probably the upgrade step wasn't run yet, so the records don't exist.
155+
pass
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
msgid ""
2+
msgstr ""
3+
"Project-Id-Version: PACKAGE VERSION\n"
4+
"POT-Creation-Date: 2026-06-17 12:10+0000\n"
5+
"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n"
6+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
7+
"Language-Team: LANGUAGE <LL@li.org>\n"
8+
"MIME-Version: 1.0\n"
9+
"Content-Type: text/plain; charset=utf-8\n"
10+
"Content-Transfer-Encoding: 8bit\n"
11+
"Plural-Forms: nplurals=1; plural=0\n"
12+
"Language-Code: de\n"
13+
"Language-Name: German\n"
14+
"Preferred-Encodings: utf-8 latin1\n"
15+
"Domain: kitconcept.website\n"
16+
17+
#: kitconcept/website/distributions.zcml:17
18+
msgid "A CMS solution for public websites. Created by kitconcept."
19+
msgstr ""
20+
21+
#: kitconcept/website/profiles.zcml:14
22+
msgid "Configure a new site based on kitconcept.website"
23+
msgstr ""
24+
25+
#: kitconcept/website/profiles/default/controlpanel.xml
26+
msgid "GDPR Settings"
27+
msgstr "DSGVO-Einstellungen"
28+
29+
#. Default: "List of 3rd-party sites to be shown in privacy preferences."
30+
#: kitconcept/website/controlpanels/dsgvo.py:56
31+
msgid "help_dsgvo_modules"
32+
msgstr "Liste der Drittanbieter-Dienste, die in den Datenschutzeinstellungen angezeigt werden."
33+
34+
#. Default: "JSON object mapping language codes to privacy policy paths or URLs. Example: {\"en\": \"/en/privacy\", \"de\": \"/de/datenschutz\"}."
35+
#: kitconcept/website/controlpanels/dsgvo.py:108
36+
#, fuzzy
37+
msgid "help_dsgvo_privacy_url"
38+
msgstr "JSON-Objekt, das Sprachcodes auf Pfade oder URLs zur Datenschutzrichtlinie abbildet. Beispiel: {\"en\": \"/en/privacy\", \"de\": \"/de/datenschutz\"}."
39+
40+
#. Default: "If true, the cookie consent banner will be shown immediately. If false, users will be prompted to accept cookies only in the context of blocks where they are needed."
41+
#: kitconcept/website/controlpanels/dsgvo.py:45
42+
msgid "help_dsgvo_show_banner"
43+
msgstr "Wenn aktiviert, wird das Cookie-Zustimmungsbanner sofort angezeigt. Wenn deaktiviert, werden Benutzer nur im Kontext von Blöcken, in denen Cookies benötigt werden, zur Zustimmung aufgefordert."
44+
45+
#. Default: "Analytics tracker to use. Choose 'google' for Google Analytics or 'matomo' for Matomo."
46+
#: kitconcept/website/controlpanels/dsgvo.py:69
47+
msgid "help_dsgvo_tracker"
48+
msgstr "Zu verwendender Analytics-Tracker. Wählen Sie 'google' für Google Analytics oder 'matomo' für Matomo."
49+
50+
#. Default: "JSON object with tracker configuration. For Google Analytics: {\"id\": \"G-XXXXXXX\", \"gaOptions\": {\"anonymizeIp\": true}}. For Matomo: {\"id\": 1, \"urlBase\": \"https://matomo.example.com/\"}."
51+
#: kitconcept/website/controlpanels/dsgvo.py:87
52+
#, fuzzy
53+
msgid "help_dsgvo_tracker_options"
54+
msgstr "JSON-Objekt mit Tracker-Konfiguration. Für Google Analytics: {\"id\": \"G-XXXXXXX\", \"gaOptions\": {\"anonymizeIp\": true}}. Für Matomo: {\"id\": 1, \"urlBase\": \"https://matomo.example.com/\"}."
55+
56+
#: kitconcept/website/distributions.zcml:17
57+
msgid "kitconcept Website"
58+
msgstr ""
59+
60+
#: kitconcept/website/profiles.zcml:14
61+
msgid "kitconcept.website"
62+
msgstr ""
63+
64+
#. Default: "Show privacy settings for"
65+
#: kitconcept/website/controlpanels/dsgvo.py:55
66+
msgid "label_dsgvo_modules"
67+
msgstr "Datenschutzeinstellungen anzeigen für"
68+
69+
#. Default: "Privacy policy URL"
70+
#: kitconcept/website/controlpanels/dsgvo.py:107
71+
msgid "label_dsgvo_privacy_url"
72+
msgstr "Datenschutzrichtlinien-URL"
73+
74+
#. Default: "Show GDPR banner on first visit"
75+
#: kitconcept/website/controlpanels/dsgvo.py:44
76+
msgid "label_dsgvo_show_banner"
77+
msgstr "DSGVO-Banner beim ersten Besuch anzeigen"
78+
79+
#. Default: "Tracker"
80+
#: kitconcept/website/controlpanels/dsgvo.py:68
81+
msgid "label_dsgvo_tracker"
82+
msgstr "Tracker"
83+
84+
#. Default: "Tracker options"
85+
#: kitconcept/website/controlpanels/dsgvo.py:86
86+
msgid "label_dsgvo_tracker_options"
87+
msgstr "Tracker-Optionen"

backend/src/kitconcept/website/locales/en/LC_MESSAGES/kitconcept.site.po

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
msgid ""
2+
msgstr ""
3+
"Project-Id-Version: PACKAGE VERSION\n"
4+
"POT-Creation-Date: 2026-06-17 12:10+0000\n"
5+
"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n"
6+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
7+
"Language-Team: LANGUAGE <LL@li.org>\n"
8+
"MIME-Version: 1.0\n"
9+
"Content-Type: text/plain; charset=utf-8\n"
10+
"Content-Transfer-Encoding: 8bit\n"
11+
"Plural-Forms: nplurals=1; plural=0\n"
12+
"Language-Code: en\n"
13+
"Language-Name: English\n"
14+
"Preferred-Encodings: utf-8 latin1\n"
15+
"Domain: kitconcept.website\n"
16+
17+
#: kitconcept/website/distributions.zcml:17
18+
msgid "A CMS solution for public websites. Created by kitconcept."
19+
msgstr ""
20+
21+
#: kitconcept/website/profiles.zcml:14
22+
msgid "Configure a new site based on kitconcept.website"
23+
msgstr ""
24+
25+
#: kitconcept/website/profiles/default/controlpanel.xml
26+
msgid "GDPR Settings"
27+
msgstr ""
28+
29+
#. Default: "List of 3rd-party sites to be shown in privacy preferences."
30+
#: kitconcept/website/controlpanels/dsgvo.py:56
31+
msgid "help_dsgvo_modules"
32+
msgstr ""
33+
34+
#. Default: "JSON object mapping language codes to privacy policy paths or URLs. Example: {\"en\": \"/en/privacy\", \"de\": \"/de/datenschutz\"}."
35+
#: kitconcept/website/controlpanels/dsgvo.py:108
36+
msgid "help_dsgvo_privacy_url"
37+
msgstr ""
38+
39+
#. Default: "If true, the cookie consent banner will be shown immediately. If false, users will be prompted to accept cookies only in the context of blocks where they are needed."
40+
#: kitconcept/website/controlpanels/dsgvo.py:45
41+
msgid "help_dsgvo_show_banner"
42+
msgstr ""
43+
44+
#. Default: "Analytics tracker to use. Choose 'google' for Google Analytics or 'matomo' for Matomo."
45+
#: kitconcept/website/controlpanels/dsgvo.py:69
46+
msgid "help_dsgvo_tracker"
47+
msgstr ""
48+
49+
#. Default: "JSON object with tracker configuration. For Google Analytics: {\"id\": \"G-XXXXXXX\", \"gaOptions\": {\"anonymizeIp\": true}}. For Matomo: {\"id\": 1, \"urlBase\": \"https://matomo.example.com/\"}."
50+
#: kitconcept/website/controlpanels/dsgvo.py:87
51+
msgid "help_dsgvo_tracker_options"
52+
msgstr ""
53+
54+
#: kitconcept/website/distributions.zcml:17
55+
msgid "kitconcept Website"
56+
msgstr ""
57+
58+
#: kitconcept/website/profiles.zcml:14
59+
msgid "kitconcept.website"
60+
msgstr ""
61+
62+
#. Default: "Show privacy settings for"
63+
#: kitconcept/website/controlpanels/dsgvo.py:55
64+
msgid "label_dsgvo_modules"
65+
msgstr ""
66+
67+
#. Default: "Privacy policy URL"
68+
#: kitconcept/website/controlpanels/dsgvo.py:107
69+
msgid "label_dsgvo_privacy_url"
70+
msgstr ""
71+
72+
#. Default: "Show GDPR banner on first visit"
73+
#: kitconcept/website/controlpanels/dsgvo.py:44
74+
msgid "label_dsgvo_show_banner"
75+
msgstr ""
76+
77+
#. Default: "Tracker"
78+
#: kitconcept/website/controlpanels/dsgvo.py:68
79+
msgid "label_dsgvo_tracker"
80+
msgstr ""
81+
82+
#. Default: "Tracker options"
83+
#: kitconcept/website/controlpanels/dsgvo.py:86
84+
msgid "label_dsgvo_tracker_options"
85+
msgstr ""

0 commit comments

Comments
 (0)