From c2c1232135334f984050639c237ac726b6f0e0c9 Mon Sep 17 00:00:00 2001 From: Ian Stride Date: Thu, 9 Nov 2023 18:37:32 +0000 Subject: [PATCH] Integrate Matomo Tag Manager --- .../0052_sitesettings_mtm_container_id.py | 27 +++++++++++++ home/models.py | 19 +++++++++ iogt/templates/base.html | 1 + matomo/templates/matomo_tag_manager.html | 10 +++++ matomo/templatetags/matomo_tags.py | 13 +++++++ matomo/tests/test_matomo_tags.py | 39 ++++++++++++++++++- 6 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 home/migrations/0052_sitesettings_mtm_container_id.py create mode 100644 matomo/templates/matomo_tag_manager.html diff --git a/home/migrations/0052_sitesettings_mtm_container_id.py b/home/migrations/0052_sitesettings_mtm_container_id.py new file mode 100644 index 000000000..4051ae295 --- /dev/null +++ b/home/migrations/0052_sitesettings_mtm_container_id.py @@ -0,0 +1,27 @@ +# Generated by Django 3.2.20 on 2023-11-09 17:56 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("home", "0051_auto_20230330_1105"), + ] + + operations = [ + migrations.AddField( + model_name="sitesettings", + name="mtm_container_id", + field=models.CharField( + blank=True, + help_text=( + "Currently this feature only works on devices using JavaScript" + " (e.g. basic featurephones are not supported), and does not work" + " with MNO zero-rating or Meta Free Basics." + ), + max_length=255, + null=True, + verbose_name="Matomo Tag Manager container ID", + ), + ), + ] diff --git a/home/models.py b/home/models.py index a1b43f669..255efbe12 100644 --- a/home/models.py +++ b/home/models.py @@ -681,6 +681,16 @@ class SiteSettings(BaseSetting): blank=True, on_delete=models.SET_NULL) opt_in_to_google_web_light = models.BooleanField(default=False) + mtm_container_id = models.CharField( + verbose_name=_("Matomo Tag Manager container ID"), + max_length=255, + null=True, + blank=True, + help_text=_( + "Currently this feature only works on devices using JavaScript (e.g. basic" + " feature phones are not supported), and does not work with MNO zero-rating" + " or Meta Free Basics.") + ) panels = [ ImageChooserPanel('logo'), @@ -754,6 +764,15 @@ class SiteSettings(BaseSetting): ], heading="Opt in to Google web light", ), + MultiFieldPanel( + [ + FieldPanel( + "mtm_container_id", + heading="Tag Manager container ID", + ), + ], + heading="Matomo", + ), ] @classmethod diff --git a/iogt/templates/base.html b/iogt/templates/base.html index 3977db654..579e0c3a3 100644 --- a/iogt/templates/base.html +++ b/iogt/templates/base.html @@ -45,6 +45,7 @@ {# Override this in templates to add extra stylesheets #} {% endblock %} {% matomo_tracking_tags %} + {% matomo_tag_manager settings.home.SiteSettings.mtm_container_id %} {% get_current_language_bidi as LANGUAGE_BIDI %} diff --git a/matomo/templates/matomo_tag_manager.html b/matomo/templates/matomo_tag_manager.html new file mode 100644 index 000000000..89cc99e60 --- /dev/null +++ b/matomo/templates/matomo_tag_manager.html @@ -0,0 +1,10 @@ +{% if mtm_src %} + + + +{% endif %} diff --git a/matomo/templatetags/matomo_tags.py b/matomo/templatetags/matomo_tags.py index 1cae9ac15..95946b711 100644 --- a/matomo/templatetags/matomo_tags.py +++ b/matomo/templatetags/matomo_tags.py @@ -10,6 +10,19 @@ register = template.Library() +@register.inclusion_tag("matomo_tag_manager.html", takes_context=True) +def matomo_tag_manager(context, container_id=None): + try: + server_url = settings.MATOMO_SERVER_URL + except AttributeError: + server_url = None + + if server_url and container_id: + context.update({"mtm_src": f"{server_url}js/container_{container_id}.js"}) + + return context + + @register.inclusion_tag("matomo_tracking_tags.html", takes_context=True) def matomo_tracking_tags(context): enabled = is_enabled() diff --git a/matomo/tests/test_matomo_tags.py b/matomo/tests/test_matomo_tags.py index fbbb6879e..aac459b79 100644 --- a/matomo/tests/test_matomo_tags.py +++ b/matomo/tests/test_matomo_tags.py @@ -1,6 +1,6 @@ from django.test import TestCase, override_settings -from matomo.templatetags.matomo_tags import matomo_tracking_tags +from matomo.templatetags.matomo_tags import matomo_tag_manager, matomo_tracking_tags @override_settings( @@ -8,7 +8,7 @@ MATOMO_SERVER_URL="https://example.com/", MATOMO_SITE_ID=456, ) -class MatomoTagsTests(TestCase): +class MatomoTrackingTagsTests(TestCase): def test_only_enabled_when_required_settings_are_set(self): self.assertTrue(matomo_tracking_tags(create_context()).get("tracking_enabled")) @@ -44,6 +44,41 @@ def test_visitor_id_is_created_for_clients_without_javascript(self): ) +class MatomoTagManagerTests(TestCase): + def test_enable_only_when_container_id_and_server_url(self): + with override_settings(MATOMO_SERVER_URL=None): + self.assertIsNone( + matomo_tag_manager( + create_context(), + container_id="ID", + ).get("mtm_src") + ) + + with override_settings(MATOMO_SERVER_URL="https://example.com/"): + self.assertIsNone( + matomo_tag_manager( + create_context(), + container_id=None, + ).get("mtm_src") + ) + self.assertIsNotNone( + matomo_tag_manager( + create_context(), + container_id="ID", + ).get("mtm_src") + ) + + def test_generate_correct_tag_manager_url(self): + with override_settings(MATOMO_SERVER_URL="https://example.com/"): + self.assertEqual( + matomo_tag_manager( + create_context(), + container_id="ID", + ).get("mtm_src"), + "https://example.com/js/container_ID.js", + ) + + class MockRequest: def __init__(self): self.session = dict()