Add support for the Spring Metrics service

This commit is contained in:
Joost Cassee 2011-10-30 16:51:26 +01:00
parent ffde47442d
commit 128014db99
7 changed files with 283 additions and 1 deletions

View file

@ -1,5 +1,6 @@
Version 0.11.0
--------------
* Added support for the Spring Metrics service.
* Allow sending events and properties to KISSmetrics (Paul Oswald).
Version 0.10.0
@ -9,7 +10,7 @@ Version 0.10.0
Version 0.9.2
-------------
* Added suppert for the SnapEngage service.
* Added support for the SnapEngage service.
* Updated Mixpanel code (Julien Grenier).
Version 0.9.1

View file

@ -33,6 +33,7 @@ Currently supported services:
* `Performable`_ web analytics and landing pages
* `Reinvigorate`_ visitor tracking
* `SnapEngage`_ live chat
* `Spring Metrics`_ conversion tracking
* `Woopra`_ web analytics
The documentation can be found in the ``docs`` directory or `read
@ -61,6 +62,7 @@ an issue to discuss your plans.
.. _Performable: http://www.performable.com/
.. _Reinvigorate: http://www.reinvigorate.com/
.. _SnapEngage: http://www.snapengage.com/
.. _`Spring Metrics`: http://www.springmetrics.com/
.. _Woopra: http://www.woopra.com/
.. _`read online`: http://packages.python.org/django-analytical/
.. _`hosted by GitHub`: http://github.com/jcassee/django-analytical

View file

@ -29,6 +29,7 @@ TAG_MODULES = [
'analytical.performable',
'analytical.reinvigorate',
'analytical.snapengage',
'analytical.spring_metrics',
'analytical.woopra',
]

View file

@ -0,0 +1,84 @@
"""
Spring Metrics template tags and filters.
"""
from __future__ import absolute_import
import re
from django.template import Library, Node, TemplateSyntaxError
from django.utils import simplejson
from analytical.utils import get_identity, is_internal_ip, disable_html, \
get_required_setting
TRACKING_ID_RE = re.compile(r'^[0-9a-f]+$')
TRACKING_CODE = """
<script type='text/javascript'>
var _springMetq = _springMetq || [];
_springMetq.push(['id', '%(tracking_id)s']);
%(custom_commands)s
(
function(){
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = ('https:' == document.location.protocol ? 'https://d3rmnwi2tssrfx.cloudfront.net/a.js' : 'http://static.springmetrics.com/a.js');
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
}
)();
</script>
"""
register = Library()
@register.tag
def spring_metrics(parser, token):
"""
Spring Metrics tracking template tag.
Renders Javascript code to track page visits. You must supply
your Spring Metrics Tracking ID in the
``SPRING_METRICS_TRACKING_ID`` setting.
"""
bits = token.split_contents()
if len(bits) > 1:
raise TemplateSyntaxError("'%s' takes no arguments" % bits[0])
return SpringMetricsNode()
class SpringMetricsNode(Node):
def __init__(self):
self.tracking_id = get_required_setting('SPRING_METRICS_TRACKING_ID',
TRACKING_ID_RE, "must be a hexadecimal string")
def render(self, context):
custom = {}
for dict_ in context:
for var, val in dict_.items():
if var.startswith('spring_metrics_'):
custom[var[15:]] = val
if 'email' not in custom:
identity = get_identity(context, 'spring_metrics',
lambda u: u.email)
if identity is not None:
custom['email'] = identity
html = TRACKING_CODE % {'tracking_id': self.tracking_id,
'custom_commands': self._generate_custom_javascript(custom)}
if is_internal_ip(context, 'SPRING_METRICS'):
html = disable_html(html, 'Spring Metrics')
return html
def _generate_custom_javascript(self, vars):
commands = ("_springMetq.push(['%s', '%s']);" % (var, val)
for var, val in vars.items())
return " ".join(commands)
def contribute_to_analytical(add_node):
SpringMetricsNode() # ensure properly configured
add_node('head_bottom', SpringMetricsNode)

View file

@ -17,5 +17,6 @@ from analytical.tests.test_tag_optimizely import *
from analytical.tests.test_tag_performable import *
from analytical.tests.test_tag_reinvigorate import *
from analytical.tests.test_tag_snapengage import *
from analytical.tests.test_tag_spring_metrics import *
from analytical.tests.test_tag_woopra import *
from analytical.tests.test_utils import *

View file

@ -0,0 +1,59 @@
"""
Tests for the Spring Metrics template tags and filters.
"""
import re
from django.contrib.auth.models import User
from django.http import HttpRequest
from django.template import Context
from analytical.templatetags.spring_metrics import SpringMetricsNode
from analytical.tests.utils import TagTestCase, override_settings, \
SETTING_DELETED
from analytical.utils import AnalyticalException
@override_settings(SPRING_METRICS_TRACKING_ID='12345678')
class SpringMetricsTagTestCase(TagTestCase):
"""
Tests for the ``spring_metrics`` template tag.
"""
def test_tag(self):
r = self.render_tag('spring_metrics', 'spring_metrics')
self.assertTrue("_springMetq.push(['id', '12345678']);" in r, r)
def test_node(self):
r = SpringMetricsNode().render(Context({}))
self.assertTrue("_springMetq.push(['id', '12345678']);" in r, r)
@override_settings(SPRING_METRICS_TRACKING_ID=SETTING_DELETED)
def test_no_site_id(self):
self.assertRaises(AnalyticalException, SpringMetricsNode)
@override_settings(SPRING_METRICS_TRACKING_ID='123xyz')
def test_wrong_site_id(self):
self.assertRaises(AnalyticalException, SpringMetricsNode)
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_identify(self):
r = SpringMetricsNode().render(Context({'user':
User(email='test@test.com')}))
self.assertTrue("_springMetq.push(['email', 'test@test.com']);" in r, r)
def test_custom(self):
r = SpringMetricsNode().render(Context({'spring_metrics_var1': 'val1',
'spring_metrics_var2': 'val2'}))
self.assertTrue("_springMetq.push(['var1', 'val1']);" in r, r)
self.assertTrue("_springMetq.push(['var2', 'val2']);" in r, r)
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
def test_render_internal_ip(self):
req = HttpRequest()
req.META['REMOTE_ADDR'] = '1.1.1.1'
context = Context({'request': req})
r = SpringMetricsNode().render(context)
self.assertTrue(r.startswith(
'<!-- Spring Metrics disabled on internal IP address'), r)
self.assertTrue(r.endswith('-->'), r)

View file

@ -0,0 +1,134 @@
=====================================
Spring Metrics -- conversion tracking
=====================================
`Spring Metrics`_ is a convesions analysis tool. It shows you the top
converting sources, search keywords ande landing pages. The real-time
dashboard shows you how customers interacted with your website and how
to increase conversion.
.. _`Spring Metrics`: http://www.springmetrics.com/
Installation
============
To start using the Spring Metrics integration, you must have installed
the django-analytical package and have added the ``analytical``
application to :const:`INSTALLED_APPS` in your project
:file:`settings.py` file. See :doc:`../install` for details.
Next you need to add the Spring Metrics template tag to your templates.
This step is only needed if you are not using the generic
:ttag:`analytical.*` tags. If you are, skip to
:ref:`spring-metrics-configuration`.
The Spring Metrics tracking code is inserted into templates using a
template tag. Load the :mod:`spring_metrics` template tag library and
insert the :ttag:`spring_metrics` tag. Because every page that you
want to track must have the tag, it is useful to add it to your base
template. Insert the tag at the bottom of the HTML head::
{% load spring_metrics %}
<html>
<head>
...
{% spring_metrics %}
</head>
...
.. _spring-metrics-configuration:
Configuration
=============
Before you can use the Spring Metrics integration, you must first set
your website Tracking ID. You can also customize the data that Spring
Metrics tracks.
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 `manage page`_
of your Spring Metrics account. Set :const:`SPRING_METRICS_TRACKING_ID`
in the project :file:`settings.py` file::
SPRING_METRICS_TRACKING_ID = 'XXXXXXXXXX'
If you do not set a Tracking ID, the tracking code will not be rendered.
.. _`manage page`: https://app.springmetrics.com/manage/
Internal IP addresses
---------------------
Usually you do not want to track clicks from your development or
internal IP addresses. By default, if the tags detect that the client
comes from any address in the :const:`SPRING_METRICS_INTERNAL_IPS`
setting, the tracking code is commented out. It takes the value of
:const:`ANALYTICAL_INTERNAL_IPS` by default (which in turn is
:const:`INTERNAL_IPS` by default). See :ref:`identifying-visitors` for
important information about detecting the visitor IP address.
Tracking revenue
----------------
The most important value tracked by Spring Metrics is that of revenue.
Using the :data:`spring_metrics_revenue` template context variable, you
can let the :ttag:`spring_metrics` tag pass earned revenue to Spring
Metrics. You can set the context variable in your view when you render
a template containing thetracking code::
context = RequestContext({'spring_metrics_revenue': '30.53'})
return some_template.render(context)
Custom data
-----------
Spring Metrics can also track other data. Interesting examples would be
transaction IDs or e-mail addresses from logged in users. By setting
any :data:`spring_metrics_X` template context variable, Spring Metrics
will track a variable named :data:`X`. For example::
context = RequestContext({
'spring_metrics_revenue': '30.53',
'spring_metrics_order_id': '15445',
})
return some_template.render(context)
Some variables should be passed on every page and can be computed from
the request object. In such cases you will want to set custom
variables in a context processor that you add to the
:data:`TEMPLATE_CONTEXT_PROCESSORS` list in :file:`settings.py`::
def spring_metrics_global_variables(request):
try:
profile = request.user.get_profile()
return {'spring_metrics_city': profile.address.city}
except (AttributeError, ObjectDoesNotExist):
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.
Identifying authenticated users
-------------------------------
If you have not set the :data:`spring_metrics_email` property
explicitly, the e-mail address of an authenticated user is passed to
Spring Metrics automatically. See :ref:`identifying-visitors`.
----
Thanks go to Spring Metrics for their support with the development of
this application.