Merge branch '2551-feature-track-events'
This commit is contained in:
commit
0cb3944ccd
18
README.rst
18
README.rst
|
@ -60,12 +60,10 @@ Installation
|
|||
Finally, there are some optional configuration settings (shown here
|
||||
with their default settings)::
|
||||
|
||||
googleanalytics.show_downloads = true
|
||||
googleanalytics.resource_prefix = /downloads/
|
||||
googleanalytics.domain = auto
|
||||
|
||||
If ``show_downloads`` is set, a download count for resources will
|
||||
be displayed on individual package pages.
|
||||
googleanalytics.show_downloads = true
|
||||
googleanalytics.track_events = false
|
||||
|
||||
``resource_prefix`` is an arbitrary identifier so that we can query
|
||||
for downloads in Google Analytics. It can theoretically be any
|
||||
|
@ -76,8 +74,16 @@ Installation
|
|||
``domain`` allows you to specify a domain against which Analytics
|
||||
will track users. You will usually want to leave this as ``auto``;
|
||||
if you are tracking users from multiple subdomains, you might want
|
||||
to specify something like ``.mydomain.com``. See `Google's
|
||||
documentation <http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setDomainName>`_ for more info.
|
||||
to specify something like ``.mydomain.com``.
|
||||
See `Google's documentation
|
||||
<http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setDomainName>`_
|
||||
for more info.
|
||||
|
||||
If ``show_downloads`` is set, a download count for resources will
|
||||
be displayed on individual package pages.
|
||||
|
||||
If ``track_events`` is set, Google Analytics event tracking will be
|
||||
enabled.
|
||||
|
||||
5. Restart CKAN (e.g. by restarting Apache)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
gacode = """
|
||||
header_code = """
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', '%s']);
|
||||
|
@ -11,3 +11,15 @@ gacode = """
|
|||
})();
|
||||
</script>
|
||||
"""
|
||||
|
||||
footer_code = """
|
||||
<script type="text/javascript" src="%s"></script>
|
||||
"""
|
||||
|
||||
download_style = """
|
||||
<style type="text/css">
|
||||
span.downloads-count {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
</style>
|
||||
"""
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
import logging
|
||||
import urllib
|
||||
import os
|
||||
from paste.deploy.converters import asbool
|
||||
from genshi.filters import Transformer
|
||||
from genshi import HTML
|
||||
from genshi.core import START, TEXT
|
||||
from genshi.filters.transform import INSIDE, EXIT
|
||||
from pylons import config, request
|
||||
from ckan.plugins import implements, SingletonPlugin
|
||||
from ckan.plugins import IGenshiStreamFilter, IConfigurable, IRoutes
|
||||
from ckan.plugins import IConfigurer
|
||||
from gasnippet import gacode
|
||||
from commands import DEFAULT_RESOURCE_URL_TAG
|
||||
import pylons
|
||||
import ckan.lib.helpers as h
|
||||
import ckan.plugins as p
|
||||
import gasnippet
|
||||
import commands
|
||||
import dbutil
|
||||
|
||||
log = logging.getLogger('ckanext.googleanalytics')
|
||||
|
@ -21,44 +19,69 @@ class GoogleAnalyticsException(Exception):
|
|||
pass
|
||||
|
||||
|
||||
class GoogleAnalyticsPlugin(SingletonPlugin):
|
||||
implements(IConfigurable, inherit=True)
|
||||
implements(IGenshiStreamFilter, inherit=True)
|
||||
implements(IRoutes, inherit=True)
|
||||
implements(IConfigurer, inherit=True)
|
||||
class GoogleAnalyticsPlugin(p.SingletonPlugin):
|
||||
p.implements(p.IConfigurable, inherit=True)
|
||||
p.implements(p.IGenshiStreamFilter, inherit=True)
|
||||
p.implements(p.IRoutes, inherit=True)
|
||||
p.implements(p.IConfigurer, inherit=True)
|
||||
|
||||
def configure(self, config):
|
||||
self.config = config
|
||||
if (not 'googleanalytics.id' in config):
|
||||
msg = "Missing googleanalytics.id in config"
|
||||
raise GoogleAnalyticsException(msg)
|
||||
|
||||
def filter(self, stream):
|
||||
log.info("Inserting GA code into template")
|
||||
ga_id = self.config['googleanalytics.id']
|
||||
ga_domain = self.config.get('googleanalytics.domain', 'auto')
|
||||
code = HTML(gacode % (ga_id, ga_domain))
|
||||
stream = stream | Transformer('head').append(code)
|
||||
resource_url = config.get('googleanalytics.resource_prefix',
|
||||
DEFAULT_RESOURCE_URL_TAG)
|
||||
ga_id = config['googleanalytics.id']
|
||||
ga_domain = config.get('googleanalytics.domain', 'auto')
|
||||
js_url = h.url_for_static('/scripts/ckanext-googleanalytics.js')
|
||||
self.resource_url = config.get('googleanalytics.resource_prefix',
|
||||
commands.DEFAULT_RESOURCE_URL_TAG)
|
||||
self.show_downloads = asbool(
|
||||
config.get('googleanalytics.show_downloads', True)
|
||||
)
|
||||
self.track_events = asbool(
|
||||
config.get('googleanalytics.track_events', False)
|
||||
)
|
||||
|
||||
routes = request.environ.get('pylons.routes_dict')
|
||||
action = routes.get('action')
|
||||
self.header_code = HTML(gasnippet.header_code % (ga_id, ga_domain))
|
||||
self.footer_code = HTML(gasnippet.footer_code % js_url)
|
||||
|
||||
def update_config(self, config):
|
||||
p.toolkit.add_template_directory(config, 'templates')
|
||||
p.toolkit.add_public_directory(config, 'public')
|
||||
|
||||
def after_map(self, map):
|
||||
map.redirect("/analytics/package/top", "/analytics/dataset/top")
|
||||
map.connect(
|
||||
'analytics', '/analytics/dataset/top',
|
||||
controller='ckanext.googleanalytics.controller:GAController',
|
||||
action='view'
|
||||
)
|
||||
return map
|
||||
|
||||
def filter(self, stream):
|
||||
log.info("Inserting Google Analytics code into template")
|
||||
|
||||
stream = stream | Transformer('head').append(self.header_code)
|
||||
|
||||
if self.track_events:
|
||||
stream = stream | Transformer('body/div[@id="scripts"]')\
|
||||
.append(self.footer_code)
|
||||
|
||||
routes = pylons.request.environ.get('pylons.routes_dict')
|
||||
action = routes.get('action')
|
||||
controller = routes.get('controller')
|
||||
|
||||
if (controller == 'package' and \
|
||||
action in ['search', 'read', 'resource_read']) or \
|
||||
(controller == 'group' and action == 'read'):
|
||||
|
||||
log.info("Tracking of resource downloads")
|
||||
show_downloads = (
|
||||
asbool(config.get('googleanalytics.show_downloads', True)) and
|
||||
action == 'read' and controller == 'package'
|
||||
)
|
||||
|
||||
# add download tracking link
|
||||
def js_attr(name, event):
|
||||
attrs = event[1][1]
|
||||
href = attrs.get('href').encode('utf-8')
|
||||
link = '%s%s' % (resource_url, urllib.quote(href))
|
||||
link = '%s%s' % (self.resource_url, urllib.quote(href))
|
||||
js = "javascript: _gaq.push(['_trackPageview', '%s']);" % link
|
||||
return js
|
||||
|
||||
|
@ -77,38 +100,15 @@ class GoogleAnalyticsPlugin(SingletonPlugin):
|
|||
yield INSIDE, (TEXT, HTML(download_html % count), pos)
|
||||
yield mark, (kind, data, pos)
|
||||
|
||||
# and some styling
|
||||
download_style = '''
|
||||
<style type="text/css">
|
||||
span.downloads-count {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
</style>
|
||||
'''
|
||||
|
||||
# perform the stream transform
|
||||
stream = stream | Transformer('//a[contains(@class, "resource-url-analytics")]')\
|
||||
.attr('onclick', js_attr)
|
||||
|
||||
if show_downloads:
|
||||
if (self.show_downloads and action == 'read' and
|
||||
controller == 'package'):
|
||||
stream = stream | Transformer('//a[contains(@class, "resource-url-analytics")]')\
|
||||
.apply(download_adder)
|
||||
stream = stream | Transformer('//head').append(HTML(download_style))
|
||||
stream = stream | Transformer('//head')\
|
||||
.append(HTML(gasnippet.download_style))
|
||||
|
||||
return stream
|
||||
|
||||
def after_map(self, map):
|
||||
map.redirect("/analytics/package/top", "/analytics/dataset/top")
|
||||
map.connect('analytics', '/analytics/dataset/top',
|
||||
controller='ckanext.googleanalytics.controller:GAController',
|
||||
action='view')
|
||||
return map
|
||||
|
||||
def update_config(self, config):
|
||||
here = os.path.dirname(__file__)
|
||||
rootdir = os.path.dirname(os.path.dirname(here))
|
||||
template_dir = os.path.join(rootdir, 'ckanext',
|
||||
'googleanalytics', 'templates')
|
||||
config['extra_template_paths'] = ','.join(
|
||||
[template_dir, config.get('extra_template_paths', '')]
|
||||
)
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
(function ($) {
|
||||
$(document).ready(function () {
|
||||
// Google Analytics event tracking
|
||||
|
||||
// group links on home page
|
||||
$('body.home div.group a').click(function() {
|
||||
_gaq.push(['_trackEvent', 'Home', 'Click: Group Link', $(this).attr('href')]);
|
||||
});
|
||||
|
||||
// clicking on user name (go to profile)
|
||||
$('div.account span.ckan-logged-in a').first().click(function() {
|
||||
_gaq.push(['_trackEvent', 'User', 'Click: User Name', $(this).attr('href')]);
|
||||
});
|
||||
|
||||
// In user profile, clicking on Edit Profile
|
||||
$('body.user div#minornavigation a')
|
||||
.filter(function(index) {return $(this).text() === "Edit Profile";})
|
||||
.click(function() {
|
||||
_gaq.push(['_trackEvent', 'User', 'Click: Tab', 'Edit Profile']);
|
||||
});
|
||||
|
||||
// Clicking Save Changes on Edit Profile page
|
||||
$('body.user.edit input#save').click(function() {
|
||||
_gaq.push(['_trackEvent', 'User', 'Click: Button', 'Save Profile Changes']);
|
||||
});
|
||||
|
||||
// Clicking on any dataset link on User Profile page
|
||||
$('body.user.read ul.datasets a').click(function() {
|
||||
_gaq.push(['_trackEvent', 'User', 'Click: Dataset Link', $(this).attr('href')]);
|
||||
});
|
||||
|
||||
// Compare Button on /dataset/history/X
|
||||
$('body.package.history form#dataset-revisions input[name="diff"]').click(function() {
|
||||
_gaq.push(['_trackEvent', 'Dataset', 'Click: Button', 'Compare History']);
|
||||
});
|
||||
|
||||
// Tags on right hand sidebar of /dataset/X
|
||||
$('body.package.read div#sidebar h3')
|
||||
.filter(function(index) {return $(this).text().indexOf("Tags") != -1;})
|
||||
.next('ul')
|
||||
.find('a')
|
||||
.click(function() {
|
||||
_gaq.push(['_trackEvent', 'Dataset', 'Click: Tag', $(this).attr('href')]);
|
||||
});
|
||||
|
||||
// Any of the group links on /group
|
||||
$('body.group.index table.groups a').click(function() {
|
||||
_gaq.push(['_trackEvent', 'Group', 'Click: Group Link', $(this).attr('href')]);
|
||||
});
|
||||
|
||||
// Clicking any of the right hand sidebar tags on /group/X
|
||||
$('body.group.read div#sidebar h2')
|
||||
.filter(function(index) {return $(this).text().indexOf("Tags") != -1;})
|
||||
.next('ul')
|
||||
.find('a')
|
||||
.click(function() {
|
||||
_gaq.push(['_trackEvent', 'Group', 'Click: Tag', $(this).attr('href')]);
|
||||
});
|
||||
|
||||
// Visiting /group/history/X
|
||||
$('body.group div#minornavigation ul.nav a')
|
||||
.filter(function(index) {return $(this).text().indexOf("History") != -1;})
|
||||
.click(function() {
|
||||
_gaq.push(['_trackEvent', 'Group', 'Click: History Tab', $(this).attr('href')]);
|
||||
});
|
||||
|
||||
// Compare Button on /group/history/X
|
||||
$('body.group.history form#group-revisions input[name="diff"]').click(function() {
|
||||
_gaq.push(['_trackEvent', 'Group', 'Click: Button', 'Compare History']);
|
||||
});
|
||||
});
|
||||
}(jQuery));
|
Loading…
Reference in New Issue