Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup wagtail-ab-testing tracking script #11889

Merged
merged 6 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@ A pages types usage report has been added on `networkapi.reports.views`, which w
### Localisation utility

The `localize_queryset` utility function on `networkapi.wagtailpages.utils` has been incorporated [into core](https://github.com/wagtail/wagtail/pull/11274). Once that has been released, the implementation here should be removed in favour of the core one.


## wagtail-ab-testing

In order to make `wagtail-ab-testing` compatible with our CSP, the main script and template tag had to be overwritten. The script on `templates/wagtail_ab_testing/script.html` was modified to pass values through a `json_script` tag (as [Django recommends](https://docs.djangoproject.com/en/4.2/ref/templates/builtins/#json-script)) and a `nonce` was added to the scripts.

The `wagtail_ab_testing_script` template tag was rewritten at `networkapi.wagtailcustomization.templatetags.wagtailcustom_tags` to pass the request to the script so that it can pick up the `nonce` value from `request` (`request.csp_nonce`).
4 changes: 3 additions & 1 deletion network-api/networkapi/templates/pages/base.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% load wagtailmetadata_tags i18n localization settings_value wagtailuserbar static mofo_common %}
{% load wagtailmetadata_tags i18n localization settings_value wagtailuserbar static mofo_common wagtailcustom_tags %}

{% get_current_language as lang_code %}

Expand Down Expand Up @@ -58,6 +58,8 @@
})(window,document,'script','FundraiseUp','ADCYPWMX');</script>
{% endblock %}

{% wagtail_ab_testing_script %}

{% block commento_meta %}{% endblock %}

{% block stylesheets %}
Expand Down
67 changes: 67 additions & 0 deletions network-api/networkapi/templates/wagtail_ab_testing/script.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{% load static %}

{% if track %}
{# Is this a Wagtail Page? #}
{% if page %}
{# This value is used to check if a goal has been reached #}
{{ page.id|json_script:"abtesting-page-id" }}
{% endif %}

{# Is there a test running on the current page? #}
{% if test and version %}
{{ test.id|json_script:"abtesting-test-id" }}
{{ version|json_script:"abtesting-version" }}
{{ test.goal_event|json_script:"abtesting-goal-event" }}
{% if test.goal_page %}
{{ test.goal_page.id|json_script:"abtesting-goal-page-id" }}
{% else %}
{{ None|json_script:"abtesting-goal-page-id" }}
{% endif %}
{% endif %}

{# URLs #}
{% url 'wagtail_ab_testing:register_participant' as register_participant_url %}
{{ register_participant_url|json_script:"abtesting-register-participant-url" }}
{% url 'wagtail_ab_testing:goal_reached' as goal_reached_url %}
{{ goal_reached_url|json_script:"abtesting-goal-reached-url" }}

<script nonce="{{ request.csp_nonce }}">
// Read values from the DOM
const registerParticipantUrl = JSON.parse(document.getElementById('abtesting-register-participant-url').textContent);
const goalReachedUrl = JSON.parse(document.getElementById('abtesting-goal-reached-url').textContent);

window.wagtailAbTesting = {
urls :{
registerParticipant: registerParticipantUrl,
goalReached: goalReachedUrl
}
};

if (document.getElementById('abtesting-page-id')) {
const pageId = JSON.parse(document.getElementById('abtesting-page-id').textContent);
window.wagtailAbTesting.pageId = pageId;
}

let testId = null;
let version = null;

if (document.getElementById('abtesting-test-id')) {
testId = JSON.parse(document.getElementById('abtesting-test-id').textContent);
}

if (document.getElementById('abtesting-version')) {
version = JSON.parse(document.getElementById('abtesting-version').textContent);
}

if (testId && version) {
const goalEvent = JSON.parse(document.getElementById('abtesting-goal-event').textContent);
const goalPageId = JSON.parse(document.getElementById('abtesting-goal-page-id').textContent);
window.wagtailAbTesting.testId = testId;
window.wagtailAbTesting.version = version;
window.wagtailAbTesting.goalEvent = goalEvent;
window.wagtailAbTesting.goalPageId = goalPageId;
}
</script>

<script nonce="{{ request.csp_nonce }}" src="{% static 'wagtail_ab_testing/js/tracker.js' %}" defer async></script>
{% endif %}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from django.utils.safestring import SafeText
from django.utils.text import slugify
from wagtail.rich_text import RichText
from wagtail_ab_testing.models import AbTest
from wagtail_ab_testing.utils import request_is_trackable

# We don't actually register any tags: the idea is to tap into
# the richtext filter, but that won't let us change _all_ the
Expand Down Expand Up @@ -85,6 +87,20 @@ def with_heading_ids(self):
return re.sub(heading_re, add_id_attribute, html)


@register.inclusion_tag("wagtail_ab_testing/script.html", takes_context=True)
def wagtail_ab_testing_script(context):
request = context["request"]
serving_variant = getattr(request, "wagtail_ab_testing_serving_variant", False)

return {
"request": request,
"track": request_is_trackable(request),
"page": context.get("page", None),
"test": getattr(request, "wagtail_ab_testing_test", None),
"version": AbTest.VERSION_VARIANT if serving_variant else AbTest.VERSION_CONTROL,
}


# Rebind the RichText's html serialization function such that
# the output is still entirely functional as far as wagtail
# can tell, except with headings enriched with fragment ids.
Expand Down
Loading