mirror of
https://github.com/jazzband/django-analytical.git
synced 2026-03-16 22:20:25 +00:00
Fix gtag user_id setup and add support for custom dimensions (#226)
* Fixed user_id setup for gtag according to latest docs * Added the possibility to include custom dimensions to be sent along with every event * Added custom dimensions section to the gtag docs * Added explicit python code blocks in the docs * Reformat test_tag_google_analytics_gtag.py with Ruff formatter
This commit is contained in:
parent
a751ffa5e3
commit
7253a3a048
3 changed files with 114 additions and 25 deletions
|
|
@ -1,7 +1,9 @@
|
|||
"""
|
||||
Google Analytics template tags and filters, using the new analytics.js library.
|
||||
Google Analytics template tags and filters, using the new gtag.js library.
|
||||
https://developers.google.com/tag-platform/gtagjs/reference
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
|
@ -23,13 +25,10 @@ SETUP_CODE = """
|
|||
function gtag(){{dataLayer.push(arguments);}}
|
||||
gtag('js', new Date());
|
||||
|
||||
{extra}
|
||||
gtag('config', '{property_id}');
|
||||
gtag('config', '{property_id}', {custom_dimensions});
|
||||
</script>
|
||||
"""
|
||||
|
||||
GTAG_SET_CODE = """gtag('set', {{'{key}': '{value}'}});"""
|
||||
|
||||
register = Library()
|
||||
|
||||
|
||||
|
|
@ -59,21 +58,15 @@ class GoogleAnalyticsGTagNode(Node):
|
|||
)
|
||||
|
||||
def render(self, context):
|
||||
other_fields = {}
|
||||
custom_dimensions = context.get('google_analytics_custom_dimensions', {})
|
||||
|
||||
identity = get_identity(context, 'google_analytics_gtag')
|
||||
identity = get_identity(context, prefix='google_analytics_gtag')
|
||||
if identity is not None:
|
||||
other_fields['user_id'] = identity
|
||||
custom_dimensions['user_id'] = identity
|
||||
|
||||
extra = '\n'.join(
|
||||
[
|
||||
GTAG_SET_CODE.format(key=key, value=value)
|
||||
for key, value in other_fields.items()
|
||||
]
|
||||
)
|
||||
html = SETUP_CODE.format(
|
||||
property_id=self.property_id,
|
||||
extra=extra,
|
||||
custom_dimensions=json.dumps(custom_dimensions),
|
||||
)
|
||||
if is_internal_ip(context, 'GOOGLE_ANALYTICS'):
|
||||
html = disable_html(html, 'Google Analytics')
|
||||
|
|
|
|||
|
|
@ -117,3 +117,52 @@ or in the template:
|
|||
{% endwith %}
|
||||
|
||||
.. _`Google Analytics conditions`: https://developers.google.com/analytics/solutions/crm-integration#user_id
|
||||
|
||||
.. _google-analytics-custom-dimensions:
|
||||
|
||||
Custom dimensions
|
||||
----------------
|
||||
|
||||
As described in the Google Analytics `custom dimensions`_ documentation
|
||||
page, you can define custom dimensions which are variables specific to your
|
||||
business needs. These variables can include both custom event parameters as
|
||||
well as customer user properties. Using the template context variable
|
||||
``google_analytics_custom_dimensions``, you can let the :ttag:`google_analytics_gtag`
|
||||
pass custom dimensions to Google Analytics automatically. The ``google_analytics_custom_dimensions``
|
||||
variable must be set to a dictionary where the keys are the dimension names
|
||||
and the values are the dimension values. You can set the context variable in your
|
||||
view when you render a template containing the tracking code::
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
context = RequestContext({
|
||||
'google_analytics_custom_dimensions': {
|
||||
'gender': 'female',
|
||||
'country': 'US',
|
||||
'user_properties': {
|
||||
'age': 25
|
||||
}
|
||||
}
|
||||
})
|
||||
return some_template.render(context)
|
||||
|
||||
Note that the ``user_properties`` key is used to pass user properties to Google
|
||||
Analytics. It's not necessary to always use this key, but that'd be the way of
|
||||
sending user properties to Google Analytics automatically.
|
||||
|
||||
You may want to set custom dimensions in a context processor that you add
|
||||
to the :data:`TEMPLATE_CONTEXT_PROCESSORS` list in :file:`settings.py`::
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def google_analytics_segment_language(request):
|
||||
try:
|
||||
return {'google_analytics_custom_dimensions': {'language': request.LANGUAGE_CODE}}
|
||||
except AttributeError:
|
||||
return {}
|
||||
|
||||
Just remember that if you set the same context variable in the
|
||||
:class:`~django.template.context.RequestContext` constructor and in a
|
||||
context processor, the latter clobbers the former.
|
||||
|
||||
.. _`custom dimensions`: https://support.google.com/analytics/answer/10075209
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from analytical.utils import AnalyticalException
|
|||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID='UA-123456-7')
|
||||
class GoogleAnalyticsTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``google_analytics_js`` template tag.
|
||||
Tests for the ``google_analytics_gtag`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
|
|
@ -25,7 +25,7 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
'<script async src="https://www.googletagmanager.com/gtag/js?id=UA-123456-7"></script>'
|
||||
) in r
|
||||
assert "gtag('js', new Date());" in r
|
||||
assert "gtag('config', 'UA-123456-7');" in r
|
||||
assert "gtag('config', 'UA-123456-7', {});" in r
|
||||
|
||||
def test_node(self):
|
||||
r = GoogleAnalyticsGTagNode().render(Context())
|
||||
|
|
@ -33,7 +33,7 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
'<script async src="https://www.googletagmanager.com/gtag/js?id=UA-123456-7"></script>'
|
||||
) in r
|
||||
assert "gtag('js', new Date());" in r
|
||||
assert "gtag('config', 'UA-123456-7');" in r
|
||||
assert "gtag('config', 'UA-123456-7', {});" in r
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID=None)
|
||||
def test_no_property_id(self):
|
||||
|
|
@ -57,7 +57,7 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify(self):
|
||||
r = GoogleAnalyticsGTagNode().render(Context({'user': User(username='test')}))
|
||||
assert "gtag('set', {'user_id': 'test'});" in r
|
||||
assert 'gtag(\'config\', \'UA-123456-7\', {"user_id": "test"});' in r
|
||||
|
||||
def test_identity_context_specific_provider(self):
|
||||
"""
|
||||
|
|
@ -68,12 +68,13 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
Context(
|
||||
{
|
||||
'google_analytics_gtag_identity': 'foo_gtag_identity',
|
||||
'analytical_identity': 'bar_analytical_identity',
|
||||
'user': User(username='test'),
|
||||
}
|
||||
)
|
||||
)
|
||||
assert "gtag('set', {'user_id': 'foo_gtag_identity'});" in r
|
||||
assert (
|
||||
'gtag(\'config\', \'UA-123456-7\', {"user_id": "foo_gtag_identity"});' in r
|
||||
)
|
||||
|
||||
def test_identity_context_general(self):
|
||||
"""
|
||||
|
|
@ -87,7 +88,10 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
}
|
||||
)
|
||||
)
|
||||
assert "gtag('set', {'user_id': 'bar_analytical_identity'});" in r
|
||||
assert (
|
||||
'gtag(\'config\', \'UA-123456-7\', {"user_id": "bar_analytical_identity"});'
|
||||
in r
|
||||
)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID='G-12345678')
|
||||
def test_tag_with_measurement_id(self):
|
||||
|
|
@ -96,7 +100,7 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
'<script async src="https://www.googletagmanager.com/gtag/js?id=G-12345678"></script>'
|
||||
) in r
|
||||
assert "gtag('js', new Date());" in r
|
||||
assert "gtag('config', 'G-12345678');" in r
|
||||
assert "gtag('config', 'G-12345678', {});" in r
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID='AW-1234567890')
|
||||
def test_tag_with_conversion_id(self):
|
||||
|
|
@ -105,7 +109,7 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
'<script async src="https://www.googletagmanager.com/gtag/js?id=AW-1234567890"></script'
|
||||
) in r
|
||||
assert "gtag('js', new Date());" in r
|
||||
assert "gtag('config', 'AW-1234567890');" in r
|
||||
assert "gtag('config', 'AW-1234567890', {});" in r
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID='DC-12345678')
|
||||
def test_tag_with_advertiser_id(self):
|
||||
|
|
@ -114,4 +118,47 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
'<script async src="https://www.googletagmanager.com/gtag/js?id=DC-12345678"></script>'
|
||||
) in r
|
||||
assert "gtag('js', new Date());" in r
|
||||
assert "gtag('config', 'DC-12345678');" in r
|
||||
assert "gtag('config', 'DC-12345678', {});" in r
|
||||
|
||||
def test_tag_with_custom_dimensions(self):
|
||||
r = GoogleAnalyticsGTagNode().render(
|
||||
Context(
|
||||
{
|
||||
'google_analytics_custom_dimensions': {
|
||||
'dimension_1': 'foo',
|
||||
'dimension_2': 'bar',
|
||||
'user_properties': {
|
||||
'user_property_1': True,
|
||||
'user_property_2': 'xyz',
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
assert (
|
||||
"gtag('config', 'UA-123456-7', {"
|
||||
'"dimension_1": "foo", '
|
||||
'"dimension_2": "bar", '
|
||||
'"user_properties": {'
|
||||
'"user_property_1": true, '
|
||||
'"user_property_2": "xyz"}});' in r
|
||||
)
|
||||
|
||||
def test_tag_with_identity_and_custom_dimensions(self):
|
||||
r = GoogleAnalyticsGTagNode().render(
|
||||
Context(
|
||||
{
|
||||
'google_analytics_gtag_identity': 'foo_gtag_identity',
|
||||
'google_analytics_custom_dimensions': {
|
||||
'dimension_1': 'foo',
|
||||
'dimension_2': 'bar',
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
assert (
|
||||
"gtag('config', 'UA-123456-7', {"
|
||||
'"dimension_1": "foo", '
|
||||
'"dimension_2": "bar", '
|
||||
'"user_id": "foo_gtag_identity"});' in r
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue