Compare commits

..

6 commits
v3.2.0 ... main

Author SHA1 Message Date
Ronard
e6f12719cc
Ask for consent - Matomo (Continuation Jayhaluska's work) (#245)
Some checks failed
Check / build (audit) (push) Has been cancelled
Check / build (docs) (push) Has been cancelled
Check / build (format) (push) Has been cancelled
Check / build (lint) (push) Has been cancelled
Check / build (package) (push) Has been cancelled
Test / python-django (4.2, 3.10) (push) Has been cancelled
Test / python-django (4.2, 3.11) (push) Has been cancelled
Test / python-django (4.2, 3.12) (push) Has been cancelled
Test / python-django (4.2, 3.9) (push) Has been cancelled
Test / python-django (5.1, 3.10) (push) Has been cancelled
Test / python-django (5.1, 3.11) (push) Has been cancelled
Test / python-django (5.1, 3.12) (push) Has been cancelled
Test / python-django (5.1, 3.13) (push) Has been cancelled
Test / python-django (5.2, 3.10) (push) Has been cancelled
Test / python-django (5.2, 3.11) (push) Has been cancelled
Test / python-django (5.2, 3.12) (push) Has been cancelled
Test / python-django (5.2, 3.13) (push) Has been cancelled
Co-authored-by: Julian Haluska <j.haluska@gmx.de>
2026-03-08 17:10:32 +01:00
Peter Bittner
694fc9097a Use up-to-date version of PyPI publish Action
Fixes an outdated reference that aborted the last release attempt.
2025-07-21 18:07:06 +02:00
Peter Bittner
10102d1017 Add Erick Massip as author for contributing via PR #226 2025-07-21 17:11:22 +02:00
Peter Bittner
033d2dc02f Align spelling of JavaScript across all files (docs, docstrings) 2025-07-21 17:11:22 +02:00
Peter Bittner
4ea4605791 Add changelog instructions, remove Gitter badge 2025-07-21 17:11:22 +02:00
Erick Massip
7253a3a048
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
2025-07-21 11:10:04 +02:00
54 changed files with 263 additions and 109 deletions

View file

@ -37,7 +37,7 @@ jobs:
- name: Upload packages to Jazzband
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@master
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: jazzband
password: ${{ secrets.JAZZBAND_RELEASE_KEY }}

View file

@ -1,3 +1,10 @@
(unreleased)
------------
* Fix GA gtag user_id setup and add support for custom dimensions (Erick Massip)
* Change spelling of "JavaScript" across all files in docstrings and docs
(Peter Bittner)
* Ask site visitors for consent when using Matomo (Julian Haluska & Ronard Luna)
Version 3.2.0
-------------
* Remove deprecated Piwik integration. Use Matomo instead! (Peter Bittner)

View file

@ -1,14 +1,14 @@
django-analytical |latest-version|
==================================
|build-status| |coverage| |python-support| |license| |gitter| |jazzband|
|build-status| |coverage| |python-support| |license| |jazzband|
The django-analytical application integrates analytics services into a
Django_ project.
.. start docs include
Using an analytics service with a Django project means adding Javascript
Using an analytics service with a Django project means adding JavaScript
tracking code to the project templates. Of course, every service has
its own specific installation instructions. Furthermore, you need to
include your unique identifiers, which then end up in the templates.
@ -19,7 +19,7 @@ behind a generic interface, and keeps personal information and
configuration out of the templates. Its goal is to make the basic
set-up very simple, while allowing advanced users to customize tracking.
Each service is set up as recommended by the services themselves, using
an asynchronous version of the Javascript code if possible.
an asynchronous version of the JavaScript code if possible.
.. end docs include
@ -38,12 +38,9 @@ an asynchronous version of the Javascript code if possible.
.. |license| image:: https://img.shields.io/pypi/l/django-analytical.svg
:alt: Software license
:target: https://github.com/jazzband/django-analytical/blob/main/LICENSE.txt
.. |gitter| image:: https://img.shields.io/gitter/room/jazzband/django-analytical.svg
:alt: Gitter chat room
:target: https://gitter.im/jazzband/django-analytical
.. |jazzband| image:: https://jazzband.co/static/img/badge.svg
:alt: Jazzband
:target: https://jazzband.co/
:target: https://jazzband.co/projects/django-analytical
.. _`Django`: http://www.djangoproject.com/
Currently Supported Services
@ -108,9 +105,7 @@ Documentation and Support
The documentation can be found in the ``docs`` directory or `read
online`_. The source code and issue tracker are generously `hosted by
GitHub`_. Bugs should be reported there, whereas for lengthy chats
and coding support when implementing new service integrations you're
welcome to use our `Gitter chat room`_.
GitHub`_.
.. _`read online`: https://django-analytical.readthedocs.io/
.. _`hosted by GitHub`: https://github.com/jazzband/django-analytical
@ -128,11 +123,17 @@ services to support, or suggesting documentation improvements, use the
the repository, make changes and place a `pull request`_. Creating an
issue to discuss your plans is useful.
At the end, don't forget to add yourself to the `list of authors`_ and
update the `changelog`_ with a short description of your contribution.
We want you to stand out from the crowd as an open source superstar! ✦
This is a `Jazzband`_ project. By contributing you agree to abide by the
`Contributor Code of Conduct`_ and follow the `guidelines`_.
.. _`issue tracker`: https://github.com/jazzband/django-analytical/issues
.. _`pull request`: https://github.com/jazzband/django-analytical/pulls
.. _`list of authors`: https://github.com/jazzband/django-analytical/blob/main/pyproject.toml
.. _`changelog`: https://github.com/jazzband/django-analytical/blob/main/CHANGELOG.rst
.. _`Jazzband`: https://jazzband.co
.. _`Contributor Code of Conduct`: https://jazzband.co/about/conduct
.. _`guidelines`: https://jazzband.co/about/guidelines

View file

@ -44,7 +44,7 @@ def chartbeat_top(parser, token):
"""
Top Chartbeat template tag.
Render the top Javascript code for Chartbeat.
Render the top JavaScript code for Chartbeat.
"""
bits = token.split_contents()
if len(bits) > 1:
@ -64,7 +64,7 @@ def chartbeat_bottom(parser, token):
"""
Bottom Chartbeat template tag.
Render the bottom Javascript code for Chartbeat. You must supply
Render the bottom JavaScript code for Chartbeat. You must supply
your Chartbeat User ID (as a string) in the ``CHARTBEAT_USER_ID``
setting.
"""

View file

@ -30,7 +30,7 @@ def clickmap(parser, token):
"""
Clickmap tracker template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your clickmap tracker ID (as a string) in the ``CLICKMAP_TRACKER_ID``
setting.
"""

View file

@ -40,7 +40,7 @@ def clicky(parser, token):
"""
Clicky tracking template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your Clicky Site ID (as a string) in the ``CLICKY_SITE_ID``
setting.
"""

View file

@ -24,7 +24,7 @@ def crazy_egg(parser, token):
"""
Crazy Egg tracking template tag.
Renders Javascript code to track page clicks. You must supply
Renders JavaScript code to track page clicks. You must supply
your Crazy Egg account number (as a string) in the
``CRAZY_EGG_ACCOUNT_NUMBER`` setting.
"""

View file

@ -33,7 +33,7 @@ def gauges(parser, token):
"""
Gaug.es template tag.
Renders Javascript code to gaug.es testing. You must supply
Renders JavaScript code to gaug.es testing. You must supply
your Site ID account number in the ``GAUGES_SITE_ID``
setting.
"""

View file

@ -71,7 +71,7 @@ def google_analytics(parser, token):
"""
Google Analytics tracking template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your website property ID (as a string) in the
``GOOGLE_ANALYTICS_PROPERTY_ID`` setting.
"""

View file

@ -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()
@ -38,7 +37,7 @@ def google_analytics_gtag(parser, token):
"""
Google Analytics tracking template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your website property ID (as a string) in the
``GOOGLE_ANALYTICS_GTAG_PROPERTY_ID`` setting.
"""
@ -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')

View file

@ -44,7 +44,7 @@ def google_analytics_js(parser, token):
"""
Google Analytics tracking template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your website property ID (as a string) in the
``GOOGLE_ANALYTICS_JS_PROPERTY_ID`` setting.
"""

View file

@ -40,7 +40,7 @@ def gosquared(parser, token):
"""
GoSquared tracking template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your GoSquared site token in the ``GOSQUARED_SITE_TOKEN`` setting.
"""
bits = token.split_contents()

View file

@ -31,7 +31,7 @@ def heap(parser, token):
"""
Heap tracker template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your heap tracker ID (as a string) in the ``HEAP_TRACKER_ID``
setting.
"""

View file

@ -30,7 +30,7 @@ def hubspot(parser, token):
"""
HubSpot tracking template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your portal ID (as a string) in the ``HUBSPOT_PORTAL_ID`` setting.
"""
bits = token.split_contents()

View file

@ -63,7 +63,7 @@ def intercom(parser, token):
"""
Intercom.io template tag.
Renders Javascript code to intercom.io testing. You must supply
Renders JavaScript code to intercom.io testing. You must supply
your APP ID account number in the ``INTERCOM_APP_ID``
setting.
"""

View file

@ -27,7 +27,7 @@ def kiss_insights(parser, token):
"""
KISSinsights set-up template tag.
Renders Javascript code to set-up surveys. You must supply
Renders JavaScript code to set-up surveys. You must supply
your account number and site code in the
``KISS_INSIGHTS_ACCOUNT_NUMBER`` and ``KISS_INSIGHTS_SITE_CODE``
settings.

View file

@ -50,7 +50,7 @@ def kiss_metrics(parser, token):
"""
KISSinsights tracking template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your KISSmetrics API key in the ``KISS_METRICS_API_KEY``
setting.
"""

View file

@ -46,6 +46,30 @@ VARIABLE_CODE = (
IDENTITY_CODE = '_paq.push(["setUserId", "%(userid)s"]);'
DISABLE_COOKIES_CODE = "_paq.push(['disableCookies']);"
GIVE_CONSENT_CLASS = 'matomo_give_consent'
REMOVE_CONSENT_CLASS = 'matomo_remove_consent'
ASK_FOR_CONSENT_CODE = """
_paq.push(['requireConsent']);
var elements = document.getElementsByClassName("{}");
for (var i = 0; i < elements.length; i++) {{
elements[i].addEventListener("click",
function () {{
_paq.push(["forgetConsentGiven"]);
}}
);
}}
var elements = document.getElementsByClassName("{}");
for (var i = 0; i < elements.length; i++) {{
elements[i].addEventListener("click",
function () {{
_paq.push(["rememberConsentGiven"]);
}}
);
}}
""".format(REMOVE_CONSENT_CLASS, GIVE_CONSENT_CLASS)
DEFAULT_SCOPE = 'page'
MatomoVar = namedtuple('MatomoVar', ('index', 'name', 'value', 'scope'))
@ -59,7 +83,7 @@ def matomo(parser, token):
"""
Matomo tracking template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your Matomo domain (plus optional URI path), and tracked site ID
in the ``MATOMO_DOMAIN_PATH`` and the ``MATOMO_SITE_ID`` setting.
@ -103,6 +127,9 @@ class MatomoNode(Node):
if getattr(settings, 'MATOMO_DISABLE_COOKIES', False):
commands.append(DISABLE_COOKIES_CODE)
if getattr(settings, 'MATOMO_ASK_FOR_CONSENT', False):
commands.append(ASK_FOR_CONSENT_CODE)
userid = get_identity(context, 'matomo')
if userid is not None:
variables_code = chain(

View file

@ -37,7 +37,7 @@ def mixpanel(parser, token):
"""
Mixpanel tracking template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your Mixpanel token in the ``MIXPANEL_API_TOKEN`` setting.
"""
bits = token.split_contents()

View file

@ -57,7 +57,7 @@ def olark(parser, token):
"""
Olark set-up template tag.
Renders Javascript code to set-up Olark chat. You must supply
Renders JavaScript code to set-up Olark chat. You must supply
your site ID in the ``OLARK_SITE_ID`` setting.
"""
bits = token.split_contents()

View file

@ -20,7 +20,7 @@ def optimizely(parser, token):
"""
Optimizely template tag.
Renders Javascript code to set-up A/B testing. You must supply
Renders JavaScript code to set-up A/B testing. You must supply
your Optimizely account number in the ``OPTIMIZELY_ACCOUNT_NUMBER``
setting.
"""

View file

@ -43,7 +43,7 @@ def performable(parser, token):
"""
Performable template tag.
Renders Javascript code to set-up Performable tracking. You must
Renders JavaScript code to set-up Performable tracking. You must
supply your Performable API key in the ``PERFORMABLE_API_KEY``
setting.
"""

View file

@ -35,7 +35,7 @@ def rating_mailru(parser, token):
"""
Rating@Mail.ru counter template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your website counter ID (as a string) in the
``RATING_MAILRU_COUNTER_ID`` setting.
"""

View file

@ -59,7 +59,7 @@ def snapengage(parser, token):
"""
SnapEngage set-up template tag.
Renders Javascript code to set-up SnapEngage chat. You must supply
Renders JavaScript code to set-up SnapEngage chat. You must supply
your widget ID in the ``SNAPENGAGE_WIDGET_ID`` setting.
"""
bits = token.split_contents()

View file

@ -40,7 +40,7 @@ def spring_metrics(parser, token):
"""
Spring Metrics tracking template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your Spring Metrics Tracking ID in the
``SPRING_METRICS_TRACKING_ID`` setting.
"""

View file

@ -35,7 +35,7 @@ def uservoice(parser, token):
"""
UserVoice tracking template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your UserVoice Widget Key in the ``USERVOICE_WIDGET_KEY``
setting or the ``uservoice_widget_key`` template context variable.
"""

View file

@ -39,7 +39,7 @@ def woopra(parser, token):
"""
Woopra tracking template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your Woopra domain in the ``WOOPRA_DOMAIN`` setting.
"""
bits = token.split_contents()

View file

@ -44,7 +44,7 @@ def yandex_metrica(parser, token):
"""
Yandex.Metrica counter template tag.
Renders Javascript code to track page visits. You must supply
Renders JavaScript code to track page visits. You must supply
your website counter ID (as a string) in the
``YANDEX_METRICA_COUNTER_ID`` setting.
"""

View file

@ -68,7 +68,7 @@ file of your project:
Adding the template tags to the base template
=============================================
Because every analytics service uses own specific Javascript code that
Because every analytics service uses own specific JavaScript code that
should be added to the top or bottom of either the head or body of the
HTML page, django-analytical provides four general-purpose template tags
that will render the code needed for the services you are using. Your

View file

@ -96,7 +96,7 @@ important information about detecting the visitor IP address.
Setting the domain
------------------
The Javascript tracking code can send the website domain to Chartbeat.
The JavaScript tracking code can send the website domain to Chartbeat.
If you use multiple subdomains this enables you to treat them as one
website in Chartbeat. If your project uses the sites framework, the
domain name of the current :class:`~django.contrib.sites.models.Site`

View file

@ -23,7 +23,7 @@ This step is only needed if you are not using the generic
:ttag:`analytical.*` tags. If you are, skip to
:ref:`clickmap-configuration`.
The Clickmap Javascript code is inserted into templates using a template
The Clickmap JavaScript code is inserted into templates using a template
tag. Load the :mod:`clickmap` template tag library and insert the
:ttag:`clickmap` tag. Because every page that you want to track must
have the tag, it is useful to add it to your base template. Insert
@ -54,7 +54,7 @@ Setting the Tracker ID
----------------------
Clickmap gives you a unique Tracker ID, and the :ttag:`clickmap`
tag will include it in the rendered Javascript code. You can find your
tag will include it in the rendered JavaScript code. You can find your
Tracker ID clicking the link named "Tracker" in the dashboard
of your Clickmap account. Set :const:`CLICKMAP_TRACKER_ID` in the project
:file:`settings.py` file::

View file

@ -53,7 +53,7 @@ Setting the Site ID
-------------------
Every website you track with Clicky gets its own Site ID, and the
:ttag:`clicky` tag will include it in the rendered Javascript code.
:ttag:`clicky` tag will include it in the rendered JavaScript code.
You can find the Site ID in the *Info* tab of the website *Preferences*
page, in your Clicky account. Set :const:`CLICKY_SITE_ID` in the
project :file:`settings.py` file::
@ -84,7 +84,7 @@ Custom data
As described in the Clicky `customized tracking`_ documentation page,
the data that is tracked by Clicky can be customized by setting the
:data:`clicky_custom` Javascript variable before loading the tracking
:data:`clicky_custom` JavaScript variable before loading the tracking
code. Using template context variables, you can let the :ttag:`clicky`
tag pass custom data to Clicky automatically. You can set the context
variables in your view when you render a template containing the

View file

@ -53,7 +53,7 @@ Setting the account number
--------------------------
Crazy Egg gives you a unique account number, and the :ttag:`crazy egg`
tag will include it in the rendered Javascript code. You can find your
tag will include it in the rendered JavaScript code. You can find your
account number by clicking the link named "What's my code?" in the
dashboard of your Crazy Egg account. Set
:const:`CRAZY_EGG_ACCOUNT_NUMBER` in the project :file:`settings.py`

View file

@ -23,7 +23,7 @@ This step is only needed if you are not using the generic
:ttag:`analytical.*` tags. If you are, skip to
:ref:`gauges-configuration`.
The Gaug.es Javascript code is inserted into templates using a
The Gaug.es JavaScript code is inserted into templates using a
template tag. Load the :mod:`gauges` template tag library and
insert the :ttag:`gauges` tag. Because every page that you want to
track must have the tag, it is useful to add it to your base template.
@ -51,7 +51,7 @@ Setting the site id
--------------------------
Gaug.es gives you a unique site id, and the :ttag:`gauges`
tag will include it in the rendered Javascript code. You can find your
tag will include it in the rendered JavaScript code. You can find your
site id by clicking the *Tracking Code* link when logged into
the on the gaug.es website. A page will display containing
HTML code looking like this::
@ -76,7 +76,7 @@ file::
GAUGES_SITE_ID = 'XXXXXXXXXXXXXXXXXXXXXXX'
If you do not set an site id, the Javascript code will not be
If you do not set an site id, the JavaScript code will not be
rendered.

View file

@ -58,7 +58,7 @@ Setting the property ID
Every website you track with Google Analytics gets its own property ID,
and the :ttag:`google_analytics` tag will include it in the rendered
Javascript code. You can find the web property ID on the overview page
JavaScript code. You can find the web property ID on the overview page
of your account. Set :const:`GOOGLE_ANALYTICS_PROPERTY_ID` in the
project :file:`settings.py` file::

View file

@ -61,7 +61,7 @@ Setting the property ID
Every website you track with Google Analytics gets its own property ID,
and the :ttag:`google_analytics_gtag` tag will include it in the rendered
Javascript code. You can find the web property ID on the overview page
JavaScript code. You can find the web property ID on the overview page
of your account. Set :const:`GOOGLE_ANALYTICS_GTAG_PROPERTY_ID` in the
project :file:`settings.py` file::
@ -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

View file

@ -61,7 +61,7 @@ Setting the property ID
Every website you track with Google Analytics gets its own property ID,
and the :ttag:`google_analytics_js` tag will include it in the rendered
Javascript code. You can find the web property ID on the overview page
JavaScript code. You can find the web property ID on the overview page
of your account. Set :const:`GOOGLE_ANALYTICS_JS_PROPERTY_ID` in the
project :file:`settings.py` file::
@ -229,7 +229,7 @@ The value is the cookie expiration in seconds or 0 to delete the cookie when the
.. _`Cookie Expiration`: https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApiBasicConfiguration#_setsessioncookietimeout
Custom Javascript Source
Custom JavaScript Source
------------------------
You can configure a custom URL for the javascript file by setting the

View file

@ -23,7 +23,7 @@ This step is only needed if you are not using the generic
:ttag:`analytical.*` tags. If you are, skip to
:ref:`intercom-configuration`.
The Intercom.io Javascript code is inserted into templates using a
The Intercom.io JavaScript code is inserted into templates using a
template tag. Load the :mod:`intercom` template tag library and
insert the :ttag:`intercom` tag. Because every page that you want to
track must have the tag, it is useful to add it to your base template.
@ -55,7 +55,7 @@ Setting the app id
--------------------------
Intercom.io gives you a unique app id, and the :ttag:`intercom`
tag will include it in the rendered Javascript code. You can find your
tag will include it in the rendered JavaScript code. You can find your
app id by clicking the *Tracking Code* link when logged into
the on the intercom.io website. A page will display containing
HTML code looking like this::
@ -71,7 +71,7 @@ file::
INTERCOM_APP_ID = 'XXXXXXXXXXXXXXXXXXXXXXX'
If you do not set an app id, the Javascript code will not be
If you do not set an app id, the JavaScript code will not be
rendered.

View file

@ -54,10 +54,10 @@ Setting the account number and site code
In order to install the survey code, you need to set your KISSinsights
account number and website code. The :ttag:`kiss_insights` tag will
include it in the rendered Javascript code. You can find the account
include it in the rendered JavaScript code. You can find the account
number and website code by visiting the code installation page of the
website you want to place the surveys on. You will see some HTML code
with a Javascript tag with a ``src`` attribute containing
with a JavaScript tag with a ``src`` attribute containing
``//s3.amazonaws.com/ki.js/XXXXX/YYY.js``. Here ``XXXXX`` is the
account number and ``YYY`` the website code. Set
:const:`KISS_INSIGHTS_ACCOUNT_NUMBER` and

View file

@ -24,7 +24,7 @@ This step is only needed if you are not using the generic
:ttag:`analytical.*` tags. If you are, skip to
:ref:`kiss-metrics-configuration`.
The KISSmetrics Javascript code is inserted into templates using a
The KISSmetrics JavaScript code is inserted into templates using a
template tag. Load the :mod:`kiss_metrics` template tag library and
insert the :ttag:`kiss_metrics` tag. Because every page that you want
to track must have the tag, it is useful to add it to your base
@ -53,7 +53,7 @@ Setting the API key
Every website you track events for with KISSmetrics gets its own API
key, and the :ttag:`kiss_metrics` tag will include it in the rendered
Javascript code. You can find the website API key by visiting the
JavaScript code. You can find the website API key by visiting the
website *Product center* on your KISSmetrics dashboard. Set
:const:`KISS_METRICS_API_KEY` in the project :file:`settings.py` file::
@ -144,7 +144,7 @@ For example::
})
return some_template.render(context)
The output script tag will then include the corresponding Javascript event as
The output script tag will then include the corresponding JavaScript event as
documented in the `KISSmetrics record API`_ docs.

View file

@ -149,6 +149,28 @@ If you want to `disable cookies`_, set :data:`MATOMO_DISABLE_COOKIES` to
.. _`disable cookies`: https://matomo.org/faq/general/faq_157/
Ask for consent
---------------
If you do not want to track visitors without permission, you can `ask for consent`_ first.
To enable this, set :data:`MATOMO_ASK_FOR_CONSENT` to :const:`True`.
By default, no consent for tracking is needed (i.e. :const:`False`).
To give and remove consent in your page, create DOM elements with the following classes:
`matomo_give_consent` - class name for element to click when visitors want to **give** consent
`matomo_remove_consent` - class name for element to click when visitors want to **remove** consent
Examples::
# button to allow tracking
<button class="matomo_give_consent">Track me!</button>
# button to remove tracking consent
<button class="matomo_remove_consent">Don't track me anymore!</button>
.. _`asking for consent`: https://developer.matomo.org/guides/tracking-javascript-guide#asking-for-consent
Internal IP addresses
---------------------

View file

@ -24,7 +24,7 @@ step is only needed if you are not using the generic
:ttag:`analytical.*` tags. If you are, skip to
:ref:`mixpanel-configuration`.
The Mixpanel Javascript code is inserted into templates using a
The Mixpanel JavaScript code is inserted into templates using a
template tag. Load the :mod:`mixpanel` template tag library and
insert the :ttag:`mixpanel` tag. Because every page that you want
to track must have the tag, it is useful to add it to your base
@ -53,7 +53,7 @@ Setting the token
-----------------
Every website you track events for with Mixpanel gets its own token,
and the :ttag:`mixpanel` tag will include it in the rendered Javascript
and the :ttag:`mixpanel` tag will include it in the rendered JavaScript
code. You can find the project token on the Mixpanel *projects* page.
Set :const:`MIXPANEL_API_TOKEN` in the project :file:`settings.py`
file::
@ -137,16 +137,16 @@ For example::
Tracking events
===============
The django-analytical app integrates the Mixpanel Javascript API in
The django-analytical app integrates the Mixpanel JavaScript API in
templates. To tracking events in views or other parts of Django, you
can use Wes Winham's `mixpanel-celery`_ package.
If you want to track an event in Javascript, use the asynchronous
If you want to track an event in JavaScript, use the asynchronous
notation, as described in the section titled
`"Asynchronous Tracking with Javascript"`_ in the Mixpanel
`"Asynchronous Tracking with JavaScript"`_ in the Mixpanel
documentation. For example::
mixpanel.track("play-game", {"level": "12", "weapon": "sword", "character": "knight"});
.. _mixpanel-celery: http://github.com/winhamwr/mixpanel-celery
.. _`"Asynchronous Tracking with Javascript"`: http://mixpanel.com/api/docs/guides/integration/js#async
.. _`"Asynchronous Tracking with JavaScript"`: http://mixpanel.com/api/docs/guides/integration/js#async

View file

@ -24,7 +24,7 @@ step is only needed if you are not using the generic
:ttag:`analytical.*` tags. If you are, skip to
:ref:`olark-configuration`.
The Olark Javascript code is inserted into templates using a template
The Olark JavaScript code is inserted into templates using a template
tag. Load the :mod:`olark` template tag library and insert the
:ttag:`olark` tag. Because every page that you want to track
must have the tag, it is useful to add it to your base template. Insert
@ -52,7 +52,7 @@ Setting the site ID
-------------------
In order to install the chat code, you need to set your Olark site ID.
The :ttag:`olark` tag will include it in the rendered Javascript code.
The :ttag:`olark` tag will include it in the rendered JavaScript code.
You can find the site ID on `installation page`_ of you Olark account.
Set :const:`OLARK_SITE_ID` in the project :file:`settings.py` file::
@ -93,7 +93,7 @@ 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.
See also `api.chat.updateVisitorNickname`_ in the Olark Javascript API
See also `api.chat.updateVisitorNickname`_ in the Olark JavaScript API
documentation.
.. _`api.chat.updateVisitorNickname`: http://www.olark.com/documentation/javascript/api.chat.updateVisitorNickname
@ -113,7 +113,7 @@ and the :ttag:`olark` tag will pass them to Olark as status messages::
]})
return some_template.render(context)
See also `api.chat.updateVisitorStatus`_ in the Olark Javascript API
See also `api.chat.updateVisitorStatus`_ in the Olark JavaScript API
documentation.
.. _`api.chat.updateVisitorStatus`: http://www.olark.com/documentation/javascript/api.chat.updateVisitorStatus

View file

@ -25,7 +25,7 @@ This step is only needed if you are not using the generic
:ttag:`analytical.*` tags. If you are, skip to
:ref:`optimizely-configuration`.
The Optimizely Javascript code is inserted into templates using a
The Optimizely JavaScript code is inserted into templates using a
template tag. Load the :mod:`optimizely` template tag library and
insert the :ttag:`optimizely` tag. Because every page that you want to
track must have the tag, it is useful to add it to your base template.
@ -53,7 +53,7 @@ Setting the account number
--------------------------
Optimizely gives you a unique account number, and the :ttag:`optimizely`
tag will include it in the rendered Javascript code. You can find your
tag will include it in the rendered JavaScript code. You can find your
account number by clicking the *Implementation* link in the top
right-hand corner of the Optimizely website. A pop-up window will
appear containing HTML code looking like this::
@ -66,7 +66,7 @@ file::
OPTIMIZELY_ACCOUNT_NUMBER = 'XXXXXXX'
If you do not set an account number, the Javascript code will not be
If you do not set an account number, the JavaScript code will not be
rendered.

View file

@ -25,7 +25,7 @@ This step is only needed if you are not using the generic
:ttag:`analytical.*` tags. If you are, skip to
:ref:`performable-configuration`.
The Performable Javascript code is inserted into templates using a
The Performable JavaScript code is inserted into templates using a
template tag. Load the :mod:`performable` template tag library and
insert the :ttag:`performable` tag. Because every page that you want to
track must have the tag, it is useful to add it to your base template.
@ -53,14 +53,14 @@ Setting the API key
-------------------
You Performable account has its own API key, which :ttag:`performable`
tag will include it in the rendered Javascript code. You can find your
tag will include it in the rendered JavaScript code. You can find your
API key on the *Account Settings* page (click 'Account Settings' in the
top right-hand corner of your Performable dashboard). Set
:const:`PERFORMABLE_API_KEY` in the project :file:`settings.py` file::
PERFORMABLE_API_KEY = 'XXXXXX'
If you do not set an API key, the Javascript code will not be rendered.
If you do not set an API key, the JavaScript code will not be rendered.
.. _performable-identity-user:
@ -116,7 +116,7 @@ Embedding a landing page
========================
You can embed a Performable landing page in your Django website. The
:ttag:`performable_embed` template tag adds the Javascript code to embed
:ttag:`performable_embed` template tag adds the JavaScript code to embed
the page. It takes two arguments: the hostname and the page ID::
{% performable_embed HOSTNAME PAGE_ID %}

View file

@ -53,7 +53,7 @@ Setting the counter ID
Every website you track with Rating\@Mail.ru gets its own counter ID,
and the :ttag:`rating_mailru` tag will include it in the rendered
Javascript code. You can find the web counter ID on the overview page
JavaScript code. You can find the web counter ID on the overview page
of your account. Set :const:`RATING_MAILRU_COUNTER_ID` in the
project :file:`settings.py` file::

View file

@ -24,7 +24,7 @@ This step is only needed if you are not using the generic
:ttag:`analytical.*` tags. If you are, skip to
:ref:`snapengage-configuration`.
The SnapEngage Javascript code is inserted into templates using a
The SnapEngage JavaScript code is inserted into templates using a
template tag. Load the :mod:`SnapEngage` template tag library and
insert the :ttag:`SnapEngage` tag. Because every page that you want to
track must have the tag, it is useful to add it to your base template.

View file

@ -53,7 +53,7 @@ Setting the Tracking ID
Every website you track with Spring Metrics gets its own Tracking ID,
and the :ttag:`spring_metrics` tag will include it in the rendered
Javascript code. You can find the Tracking ID in the `Site Settings`_
JavaScript code. You can find the Tracking ID in the `Site Settings`_
of your Spring Metrics account. Set :const:`SPRING_METRICS_TRACKING_ID`
in the project :file:`settings.py` file::

View file

@ -29,7 +29,7 @@ This step is only needed if you are not using the generic
:ttag:`analytical.*` tags. If you are, skip to
:ref:`uservoice-configuration`.
The UserVoice Javascript code is inserted into templates using a
The UserVoice JavaScript code is inserted into templates using a
template tag. Load the :mod:`uservoice` template tag library and insert
the :ttag:`uservoice` tag. Because every page that you want to have
the feedback tab to appear on must have the tag, it is useful to add
@ -57,8 +57,8 @@ Setting the widget key
In order to use the feedback widget, you need to configure which widget
you want to show. You can find the widget keys in the *Channels* tab on
your UserVoice *Settings* page. Under the *Javascript Widget* heading,
find the Javascript embed code of the widget. The widget key is the
your UserVoice *Settings* page. Under the *JavaScript Widget* heading,
find the JavaScript embed code of the widget. The widget key is the
alphanumerical string contained in the URL of the script imported by the
embed code::

View file

@ -37,7 +37,7 @@ the tag at the bottom of the HTML head::
</head>
...
Because Javascript code is asynchronous, putting the tag in the head
Because JavaScript code is asynchronous, putting the tag in the head
section increases the chances that a page view is going to be tracked
before the visitor leaves the page. See for details the `Asynchronous
JavaScript Developers Guide`_ on the Woopra website.

View file

@ -53,7 +53,7 @@ Setting the counter ID
Every website you track with Yandex.Metrica gets its own counter ID,
and the :ttag:`yandex_metrica` tag will include it in the rendered
Javascript code. You can find the web counter ID on the overview page
JavaScript code. You can find the web counter ID on the overview page
of your account. Set :const:`YANDEX_METRICA_COUNTER_ID` in the
project :file:`settings.py` file::

View file

@ -25,6 +25,7 @@ authors = [
{name = "Eric Amador", email = "eric.amador14@gmail.com"},
{name = "Eric Davis", email = "eric@davislv.com"},
{name = "Eric Wang", email = "gnawrice@gmail.com"},
{name = "Erick Massip", email = "ericmassip1@gmail.com"},
{name = "Garrett Coakley", email = "garrettc@users.noreply.github.com"},
{name = "Garrett Robinson", email = "garrett.f.robinson@gmail.com"},
{name = "GreenKahuna", email = "info@greenkahuna.com"},
@ -58,6 +59,8 @@ authors = [
{name = "Tinnet Coronam", email = "tinnet@coronam.net"},
{name = "Uros Trebec", email = "uros@trebec.org"},
{name = "Walter Renner", email = "walter.renner@me.com"},
{name = "Julian Haluska", email = "mail@julianhaluska.de"},
{name = "Ronard Luna", email = "rlunag@proton.me"},
]
maintainers = [
{name = "Jazzband community", email = "jazzband-bot@users.noreply.github.com"},

View file

@ -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
)

View file

@ -159,3 +159,8 @@ class MatomoTagTestCase(TagTestCase):
def test_disable_cookies(self):
r = MatomoNode().render(Context({}))
assert "_paq.push(['disableCookies']);" in r
@override_settings(MATOMO_ASK_FOR_CONSENT=True)
def test_ask_for_consent(self):
r = MatomoNode().render(Context({}))
self.assertTrue("_paq.push(['requireConsent']);" in r, r)