From a5f0134d6d2e28bbf48ec3ce38f6a6529373779e Mon Sep 17 00:00:00 2001 From: Reto Tschuppert Date: Mon, 30 Dec 2024 16:12:01 +0100 Subject: [PATCH 1/3] Adds string field for web statistics url --- src/onegov/org/forms/settings.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/onegov/org/forms/settings.py b/src/onegov/org/forms/settings.py index dec4b95263..59af64af6b 100644 --- a/src/onegov/org/forms/settings.py +++ b/src/onegov/org/forms/settings.py @@ -777,6 +777,34 @@ class AnalyticsSettingsForm(Form): description=_('JavaScript for web statistics support'), render_kw={'rows': 10, 'data-editor': 'html'}) + # Points the user to the analytics url e.g. matomo or plausible + analytics_url = StringField( + label=_('Analytics URL'), + description=_('URL pointing to the analytics page'), + render_kw={'readonly': True}, + validators=[UrlRequired(), Optional()], + ) + + def derive_analytics_url(self) -> str: + analytics_code = self.analytics_code.data or '' + + if 'analytics.seantis.ch' in analytics_code: + data_domain = analytics_code.split( + 'data-domain="', 1)[1].split('"', 1)[0] + return f'https://analytics.seantis.ch/{data_domain}' + elif 'matomo' in analytics_code: + return 'https://stats.seantis.ch' + else: + return '' + + def populate_obj(self, model: 'Organisation') -> None: # type:ignore + super().populate_obj(model) + + def process_obj(self, model: 'Organisation') -> None: # type:ignore + super().process_obj(model) + + self.analytics_url.data = self.derive_analytics_url() + class HolidaySettingsForm(Form): From 0a5937f63cb7e0c1bf77d1f51adadc275e663ed1 Mon Sep 17 00:00:00 2001 From: Reto Tschuppert Date: Mon, 30 Dec 2024 16:37:36 +0100 Subject: [PATCH 2/3] Adds test --- tests/onegov/town6/test_views_settings.py | 39 +++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/onegov/town6/test_views_settings.py b/tests/onegov/town6/test_views_settings.py index 10f9b59df1..c0c647f4c1 100644 --- a/tests/onegov/town6/test_views_settings.py +++ b/tests/onegov/town6/test_views_settings.py @@ -76,3 +76,42 @@ def test_general_settings(client): assert '' in page assert 'class="header-image"' in page + + +def test_analytics_settings(client): + # plausible + client.login_admin() + + code = ('') + settings = client.get('/analytics-settings') + settings.form['analytics_code'] = code + settings.form.submit() + + settings = client.get('/analytics-settings') + assert 'https://analytics.seantis.ch/govikon.ch' in settings + + # matomo + code = """ + + + +""" + settings = client.get('/analytics-settings') + settings.form['analytics_code'] = code + settings.form.submit() + + settings = client.get('/analytics-settings') + assert 'https://stats.seantis.ch' in settings From 77935dc79d9cfd729daf10573986ccda371d88fb Mon Sep 17 00:00:00 2001 From: Reto Tschuppert Date: Tue, 31 Dec 2024 11:28:39 +0100 Subject: [PATCH 3/3] Use a url panel field to make url clickable --- src/onegov/form/fields.py | 7 ++++++- src/onegov/form/widgets.py | 15 +++++++++++++++ src/onegov/org/forms/settings.py | 10 ++++++---- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/onegov/form/fields.py b/src/onegov/form/fields.py index 69001f08c0..2555e4594c 100644 --- a/src/onegov/form/fields.py +++ b/src/onegov/form/fields.py @@ -16,7 +16,7 @@ from onegov.form import log, _ from onegov.form.utils import path_to_filename from onegov.form.validators import ValidPhoneNumber -from onegov.form.widgets import ChosenSelectWidget +from onegov.form.widgets import ChosenSelectWidget, LinkPanelWidget from onegov.form.widgets import HoneyPotWidget from onegov.form.widgets import IconWidget from onegov.form.widgets import MultiCheckboxWidget @@ -676,6 +676,11 @@ def populate_obj(self, obj: object, name: str) -> None: pass +class URLPanelField(PanelField): + + widget = LinkPanelWidget() + + class DateTimeLocalField(DateTimeLocalFieldBase): """ A custom implementation of the DateTimeLocalField to fix issues with the format and the datetimepicker plugin. diff --git a/src/onegov/form/widgets.py b/src/onegov/form/widgets.py index dea09bb778..e5a77b93f4 100644 --- a/src/onegov/form/widgets.py +++ b/src/onegov/form/widgets.py @@ -519,6 +519,21 @@ def __call__(self, field: 'PanelField', **kwargs: Any) -> Markup: ) +class LinkPanelWidget(PanelWidget): + """ A widget that displays a clickable link as panel (no input). """ + + def __call__(self, field: 'PanelField', **kwargs: Any) -> Markup: + text = escape(field.meta.request.translate(field.text)) + return Markup( # noqa: RUF035 + f'
' + '{text}
' + ).format( + kind=field.kind, + text=text.replace('\n', Markup('
')), + link=field.text + ) + + class HoneyPotWidget(TextInput): """ A widget that displays the input normally not visible to the user. """ diff --git a/src/onegov/org/forms/settings.py b/src/onegov/org/forms/settings.py index 59af64af6b..bf304996d1 100644 --- a/src/onegov/org/forms/settings.py +++ b/src/onegov/org/forms/settings.py @@ -9,7 +9,7 @@ from onegov.core.widgets import transform_structure from onegov.core.widgets import XML_LINE_OFFSET from onegov.form import Form -from onegov.form.fields import ChosenSelectField +from onegov.form.fields import ChosenSelectField, URLPanelField from onegov.form.fields import ColorField from onegov.form.fields import CssField from onegov.form.fields import MarkupField @@ -778,11 +778,14 @@ class AnalyticsSettingsForm(Form): render_kw={'rows': 10, 'data-editor': 'html'}) # Points the user to the analytics url e.g. matomo or plausible - analytics_url = StringField( + analytics_url = URLPanelField( label=_('Analytics URL'), description=_('URL pointing to the analytics page'), render_kw={'readonly': True}, validators=[UrlRequired(), Optional()], + text='', + kind='panel', + hide_label=False ) def derive_analytics_url(self) -> str: @@ -802,8 +805,7 @@ def populate_obj(self, model: 'Organisation') -> None: # type:ignore def process_obj(self, model: 'Organisation') -> None: # type:ignore super().process_obj(model) - - self.analytics_url.data = self.derive_analytics_url() + self.analytics_url.text = self.derive_analytics_url() class HolidaySettingsForm(Form):