Google Analytics Plugin

(AKA ‘my first plugin’)

Since the existing one from the Plugins page on the rails wiki isn’t resolving correctly, I’ve created my own Google Analytics plugin. I got fed up adding the same chunk of code to app/views/layouts/application.rhtml for every new application. So hopefully this will make things nice and easy.

To install it, add my plugin repository to your rails plugin sources:

script/plugin source http://svn.rubaidh.com/plugins/trunk

and to install the Google Analytics plugin:

script/plugin install google_analytics

To configure it, add the following to config/environment.rb:

Rubaidh::GoogleAnalytics.tracker_id = 'UA-12345-67'

where the tracker_id is what _uacct gets set to in the chunk of javascript that Google gives you to insert. That’s it! All configured! Your tracking information will be inserted into every page. If you don’t want it in particular controller, you can do the usual to skip after_filters:

skip_after_filter :add_google_analytics_code

Simple, eh?

Update 2006/05/10 I’ve updated plugin so that it should automatically use the SSL version of the Google Analytics URL if it’s on an SSL page (so that you don’t get warnings about a mixture of secure and insecure content on a page). I’ve also added support for specifying the _udn which you’ll want to put in if you have multiple subdomains appearing on the same report.

32 thoughts on “Google Analytics Plugin

  1. Great idea!

    Havn’t had a chance to look at the code yet but does it handle ssl and non-ssl pages? (ie, switches the google analytics url to prevent non-ssl items on ssl pages)

  2. Kevin: Done. :) I’ve not tested it, though, because I’ve not got a site deployed on SSL. Could you try it out and let me know if it works OK?

  3. Pingback: Plugs and plugins at Notes from a messy desk

  4. Would love to try this out, but I can’t get an analytics account. Any chance you have an invitation code laying around?

  5. Great plugin! I just wanted to write my own Analytics plugins, but a quick Google revealed this.

    It might be worth pointing out that placing the configuration line in config/enviroment/production.rb ensures that no analytics code is present while developing.

    Keep up the good work!

  6. Kenneth: Thanks! While placing the configuration line in config/environment/production.rb is probably more flexible (it’ll allow you to specifically configure it for any individual environment you use), I’ve opted for convention over configuration and the plugin only ever emits the Google Analytics code when the environment is production anyway.

  7. I found this link and got interested since I just started using Typo.

    Only problem is, when I try the first step, I get this:

    ruby script/plugin source http://svn.rubaidh.com/plugins/trunk ./script/../config/../vendor/rails/railties/lib/commands/plugin.rb:301:in <<': can't modify frozen string (TypeError) from ./script/../config/../vendor/rails/railties/lib/commands/plugin.rb:301:ininitialize’ from ./script/../config/../vendor/rails/railties/lib/commands/plugin.rb:220:in add' from ./script/../config/../vendor/rails/railties/lib/commands/plugin.rb:530:inparse!’ from ./script/../config/../vendor/rails/railties/lib/commands/plugin.rb:529:in parse!' from ./script/../config/../vendor/rails/railties/lib/commands/plugin.rb:411:inparse!’ from ./script/../config/../vendor/rails/railties/lib/commands/plugin.rb:427:in `parse!’ from ./script/../config/../vendor/rails/railties/lib/commands/plugin.rb:823 from script/plugin:3

  8. Pingback: Google Analytics plugin with typo?

  9. I was able to follow the steps without issues – I’m attempting to get it to work with the Typo blog that I have setup. Interestingly, it adds the javascript to the admin pages, but doesn’t seem to add the javascript to the main page!

  10. It works – I just confirmed it. In Typo – just make sure you unload and reload the theme and it will show up. Thank you very much for this. There is very little out there on using google analytics – especially with the Typo blogging software.

  11. Ive got a question regarding google analytics and rails. I have copied the code snippet from google and I have it placed in a footer that is included on all pages. Goole sees the script but no data is being sent. has anybody had this trouble? Thanks.

  12. Bill: You’ve got a space between the underscore and the uacct in the code you’ve pasted (looking at goodwidgets.com). Try removing the extraneous space, or consider just using the plugin which takes care of it all for you. :-)

  13. What I want to do on my blog, is every few hours take the oldest post and move it to the front of the queue, all automatically. Anyone know if there is a plugin that can do this or a simple way to set up another plugin to do this (use my own feed perhaps)? Thanks.

  14. Hey mathie,

    I’ve been using this plugin and it it seems to work very nicely – I have come across one issue/bug though…

    When attempting to render an inline PDF from one of my controllers using the following code:

    send_file(pdf_filename, :type => document.content_type, :disposition => ‘inline’)

    The plugin barfs as it tries to do the replace on the body tag replace (which of course doesn’t exist):

    NoMethodError (private method gsub!' called for #<Proc:0xb7863fa0>): /vendor/plugins/google_analytics/lib/rubaidh/google_analytics.rb:12:inadd_google_analytics_code’

    I guess the #add_google_analytics_code method just needs to be extended to catch that exception and ignore it.

    Cheers, James.

  15. P.S. As an aside, it would also be nice to have a link to details about available comment formatting markup by the Leave a Reply form.

  16. Here’s my monkeypatch for anyone facing the issue I mentioned above:

    http://attachr.com/6734

    I’ve stuck it in lib/patches/google_analytics/google_analytics.rb and then just required it from my environment.rb. Seems to do the trick.

    J.

  17. I am having trouble getting the https to work correctly, it is outputting http link to Google on https pages. I followed the one simple instruction (nice!) to add to environment.rb and that is about it. Is there something else I need to do? I am using apache/mongrel_cluster/rails.

  18. James: OK, only 4 month late, but I’ve finally actually used my GA plugin on another project so I’ve tweaked it so that it only tries to spit out the GA code if the response actually responds to gsub!. More or less the same as your monkey patch but more duck-like. :)

    Thanks for the pointer!

  19. Graeme,

    may be it is worth checking whether format is text/html:

    Index: vendor/plugins/google_analytics/lib/rubaidh/google_analytics.rb

    --- vendor/plugins/google_analytics/lib/rubaidh/google_analytics.rb (revision 247) vendor/plugins/google_analytics/lib/rubaidh/google_analytics.rb (working copy) @@ -9,7 9,7 @@ def add_google_analytics_code code = google_analytics_code(request) return if code.blank? - response.body.gsub! '', code '' if response.body.respond_to?(:gsub!) response.body.gsub! '', code '' if request.format == 'text/html' and response.body.respond_to?(:gsub!) end end

  20. Hi. Looks like just the thing, but unfortunately it’s keeling over at startup for me :0((. I’m using rails 1.2.3 and it does the same thing in either production of development mode …

    ** Starting Rails with development environment… Exiting /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:266:in load_missing_constant': uninitialized constant Rubaidh (NameError) from /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:452:inconst_missing’ from /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:464:in const_missing' from /Users/attila/src/trunk/config/environment.rb:115 from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:ingem_original_require’ from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in require' from /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:inrequire’ from /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:342:in new_constants_in' from /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:inrequire’ … 21 levels… from /usr/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/server.rb:39 from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in gem_original_require' from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:inrequire’ from script/server:3

    Any ideas ?. Would be nice to use if I can get past this little hickup :0).

    Thanks.

  21. Hi, How can I test google analytics at the development stage ? In Rubaidh::GoogleAnalytics.domain_name = ‘example.com’, what should be the domain name in the development environment ?

  22. Nice work! I’d be interested in seeing a GA plugin that could handle goals too. Like a snippet you could add to a controller that was part of a goal.

  23. Hi,

    I’ve took the liberty to modify your plugin so that it will also track ajax calls and check the content type of the response.

    Here it is:

    module Rubaidh # :nodoc: module GoogleAnalyticsMixin def google_analytics_code(request = nil, headers = nil, flash = nil) return unless GoogleAnalytics.enabled? GoogleAnalytics.google_analytics_code(request, headers, flash) end

    # An after_filter to automatically add the analytics code.
    def add_google_analytics_code
      if response.body.index("</body>")
        code = google_analytics_code(request)
        response.body.gsub! '</body>', code + '</body>' if response.body.respond_to?(:gsub!) && !code.nil?
      elsif response.body.is_a? String # if an Ajax call there won't be a body tag
        code = google_analytics_code(request, headers, flash)
        response.body << code unless code.nil?
      end
    end

    A before_filter to automatically store the last accessed url in a cookie

    so it can be retrieved form JavaScript to send it back to google when an

    Ajax call was made.

    def add_google_analytics_url options = { :controller => self.controller_name(), :action => self.action_name(), :o nly_path => true }.merge(params) flash[:urchin] = "\"#{url_for(options)}\"" end

    end

    class GoogleAnalytics # Specify the Google Analytics ID for this web site. This can be found # as the value of +_uacct+ in the Javascript excerpt @@tracker_id = nil cattr_accessor :tracker_id

    # Specify a different domain name from the default.  You'll want to use

    this if you have several subdomains that you want to combine into

    one report. See the Google Analytics documentation for more

    information.

    @@domain_name = nil cattr_accessor :domain_name

    I can't see why you'd want to do this, but you can always change the

    analytics URL.

    @@analytics_url = 'http://www.google-analytics.com/urchin.js' cattr_accessor :analytics_url

    I can't see why you'd want to do this, but you can always change the

    analytics URL (ssl version).

    @@analytics_ssl_url = 'https://ssl.google-analytics.com/urchin.js' cattr_accessor :analytics_ssl_url

    The environments in which to enable the Google Analytics code. Defaults

    to 'production' only.

    @@environments = ['development','test','production'] cattr_accessor :environments

    Return true if the Google Analytics system is enabled and configured

    correctly.

    def self.enabled? (environments.include?(RAILS_ENV) and not tracker_id.blank? and not analytics_url.blank?) end

    def self.google_analytics_code(request = nil, headers = nil, flash = nil) extra_code = domain_name.blank? ? nil : "_udn = \"#{domain_name}\";\n" url = (not request.blank? and request.ssl?) ? analytics_ssl_url : analytics_url path = "'#{path}'" unless path.nil? code = "try {\n_uacct = \"#{tracker_id}\";\n#{extra_code}urchinTracker(#{flash ? flash[:urchin] : nil});}\ncatch(e) {}" # OK, I'm not very bright -- I tried to turn this into a partial and # failed miserably! So it'll have to live here for now. if headers && headers["Content-Type"].to_s.index("javascript") # if content is javascript only (e.g. RJS), just append the javascript code without the html tags return code elsif headers.nil? || (headers["Content-Type"].nil? || headers["Content-Type"].to_s === "text/html") # if content is blank or html, append the javascript code with the html tags return <<-HTML <script src="#{url}" type="text/javascript"></script> <script type="text/javascript"> //<![CDATA[ #{code} //]]> </script> HTML end end

    end end

  24. Hi,

    This url is not working. I am not able to download this plugin.

    Thanks & Regards Ganesh Mohan