Reply to comment
Apache2 Filters - Adding Google Analytics to all pages
Submitted by steven on Tue, 10/30/2007 - 20:07
This week I wanted to add java script based Google Analytics to my Apache 2.0 content on evatt.com. This included Joomla, Drupal, Squirrelmail, Nagios, Gallery, amongst other stuff. When I faced this problem a couple years ago with Apache 1.3, I was able to solve it using Apache::Sandwich. After some research, I discovered the Apache 2.0 solution is to make custom filters.
My solution had the following constraints. Since I had already added the Google Analytics code to some of my Joomla templates, the filter needed to be smart enough to only apply its self to pages that did not include the code. I am also inserting the code just before the close body tag </body>.
To use my code, you will need to do the following:
1) Create a Google Analytics account.
2) Put the code in your site_perl directory (The code is at the end). For me, the file is:
/usr/local/lib/site_perl/Filters/GoogleAnalytics.pm
3) The code needs two small modifications. There are two spots where
UA-XXXXXXX-1 needs to be replaced with your Google Analytics
identification.
4) Add the following to your Apache2 configuration. For me, the configuration file is :
/etc/apache2/sites-enabled/000-default
-------------------------------------
PerlLoadModule Filters::GoogleAnalytics
<Files *.html>
PerlOutputFilterHandler Filters::GoogleAnalytics
AddGoogleTag
</Files>
<Files *.php>
PerlOutputFilterHandler Filters::GoogleAnalytics
AddGoogleTag
</Files>
-------------------------------------
These lines should be modified to represent the type of files you would like the Google Analytics code added to.
Good Luck
-------------------------------------------------------------------------------------
package Filters::GoogleAnalytics; ## Steven Evatt - 2007/10/29 use strict; use Apache2::Filter (); use Apache2::Const -compile => qw(OK OR_ALL NO_ARGS); use Apache2::Module (); use Apache2::CmdParms; use Apache2::RequestRec (); use APR::Table; #use constant BUFF_LEN => 1024; use constant BUFF_LEN => 8000; # There is perldoc at the end of this file. my @directives = ( { name => 'AddGoogleTag', func => __PACKAGE__ . '::AddGoogleTag', req_override => Apache2::Const::OR_ALL, args_how => Apache2::Const::NO_ARGS, errmsg => 'AddGoogleTag', }, ); Apache2::Module::add(__PACKAGE__, \@directives); sub AddGoogleTag { my ($self, $parms, @args) = @_; } sub handler { my $f = shift; # unset Content-Length but only on the first bucket per response. unless ($f->ctx) { $f->r->headers_out->unset('Content-Length'); $f->ctx(1); } # read from the incoming brigade while ($f->read(my $buffer, BUFF_LEN)) { # get the config for this module, # so we can access the directive's arguments my $cfg = Apache2::Module::get_config(__PACKAGE__, $f->r->server); # do the switch! my $google_in ="</body>"; my $google_out = <<EOF; <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"> </script> <script type="text/javascript"> _uacct = "UA-XXXXXXX-X"; urchinTracker(); </script> </body> EOF chomp $google_out; if ($buffer =~ m|</body>|i) { unless ($buffer =~ m/UA-XXXXXXX-X/) { $buffer =~ s/$google_in/$google_out/i; } } $f->print($buffer); # write to the outgoing brigade } return Apache2::Const::OK; } ### 1;# ### =head1 NAME Filters::GoogleAnalytics =head1 SYNOPSIS The following is not Perl; it goes in your Apache vhost configuration. (for example, /etc/apache2/sites-enabled/000-default) PerlLoadModule Filters::GoogleAnalytics <Files *.html> PerlOutputFilterHandler Filters::GoogleAnalytics AddGoogleTag </Files> <Files *.php> PerlOutputFilterHandler Filters::GoogleAnalytics AddGoogleTag </Files> =head1 DESCRIPTION This filter inserts your Google Analytic Javascript tag before the </body> tag if the page does not already contain the Google tag. This is an output filter for Apache2. It will NOT work with apache 1.3. You need to modify this .pm file to insert your google tag, and add a few lines to your apache configuration. See the L<synopsis> for a somewhat complete example. To use this module as shown, you will need: * Apache version 2 * Mod_perl version 2 =head1 Directives =over 12 =item C<AddGoogleTag> Takes no arguments. AddGoogleTag Inserts your google tag just before the </body> tag on the page. =back =head1 LICENSE GPL. =head1 AUTHOR Steven Evatt =head1 SEE ALSO Apache2::Filter mod_perl The excellent tutorial at http://perl.apache.org/docs/2.0/user/handlers/filters.html =cut