Automatic Analytics Tracking Code Insertion with PHP

Say you're creating a purely static website on a regular old php-enabled webhost. Let's say you're doing this with iWeb on Dreamhost for some reason. Don't ask.

Now say you want to track the site with Google Analytics. iWeb has no way to insert raw code, and definitely no way to do it across all pages.

Try this...

.htaccess

# Interpret html as php
AddHandler application/x-httpd-php .html

# Required so the xml prolog isn't intepreted as php
php_flag short_open_tag false

# Wrap all requests and add google analytics tracking code
php_value auto_prepend_file '_prepend.php'
php_value auto_append_file '_append.php'

_prepend.php

<?php
  ob_start();
?>

_append.php

<?php
  $body = ob_get_contents();
  ob_end_clean();

  # If the page has a  </body> tag
  if (preg_match('/<\/body>/', $body)) {

    # get the GA script tags
    ob_start();
    include("_google_analytics.txt");
    $google_analytics = ob_get_contents();
    ob_end_clean();

    # Add GA to the document
    $body_with_analytics = preg_replace('/<\/body>/', "$google_analytics</body>", $body);

    # Write the page with GA
    print($body_with_analytics);

  # Else just write the page
  } else {
    print($body);
  }
?>

_google_analytics.txt


<your GA tracking code>

Hey, it works.

Google Analytics, shiny & new

Today we launched a new version of Google Analytics.

It's been a long and difficult road, but I'm really happy with the result. Hey, I even wrote some Flash again!

Hope you enjoy it.

A bad way to start the day

Committed revision 666.

Strong is a weakness

Just ran across Is Weak Typing Strong Enough?, one of Steve Yegge's rants. It might be old news, but what a great comparison. First, he provides an argument for either side, one I totally agree with.

Above all, we need stability. We have enormous scale and massive business complexity. To create order out of inevitable chaos, we need rigorous modeling for both our code and our data. If we don't get the model and architecture mostly correct in the beginning, it will hurt us later, so we'd better invest a lot of effort in up-front design. We need hardened interfaces — which means static typing by definition, or users won't be able to see how to use the interfaces. We need to maximize performance, and this requires static types and meticulous data models. Our most important business advantages are the stability, reliability, predictability and performance of our systems and interfaces. Viva SOAP (or CORBA), UML and rigorous ERDs, DTDs or schemas for all XML, and {C++|Java|C#|OCaml|Haskell|Ada}.

Above all, we need flexibility. Our business requirements are constantly changing in unpredictable ways, and rigid data models rarely anticipate these changes adequately. Small teams need to be able to deliver quickly on their own goals, yet simultaneously keep up with rapid changes in the rest of the business. Hence we should use flexible, expressive languages and data models, even if it increases the cost of achieving the performance we need. We can achieve sufficient reliability through a combination of rigorous unit testing and agile development practices. Our most important business advantage is our ability to deliver on new initiatives quickly. Viva XML/RPC and HTTP, mandatory agile programming, loose name/value pair modeling for both XML and relational data, and {Python|Ruby|Lisp|Smalltalk|Erlang}

But then he follows that up with

The first camp only resorts to dynamic typing when they're backed into a corner.

The second camp only resorts to performance optimizations and interface/schema lockdowns when backed into a corner.

Now, it seems so obvious which is the more logical approach.

  • With strong, you're forced to create a weaker system when (not if) unexpected requirements come up. The problem is, those weak spots are guaranteed spread through the system, causing a clash of philosphies all over your code.
  • With weak, you simply beef up error handling a bit or choose another technology when necessary. Because the entire system was built with a weak mentality, you haven't lost any additional stability.

So next time this argument comes up, just figure out what you're really building and choose the right one. I bet 99 out of 100 times you'll go weak.

  • July 1, 2006
  • Dealing with coding

SF Ruby Meeting

Ok, this is super late notice but I'll be at the San Francisco Ruby Meetup tonight, May 9 to give a quick demo of Measure Map. Josh Susser, who's been writing good things at has_many :through will be presenting on how to contribute to Rails.

yes, it's been almost three months since my last post. yes google is keeping me busy. yes I'll try to do something here more often. if you really care what I'm up to, please check my flickr stream.

One more thing...

As if enough things hadn't been going on, Measure Map is now part of Google! There's no telling what the future will bring, but for now you can read our introduction on the Google Blog.

I'm super excited for the endless possibilities this means for our little team and the future of tracking web sites.

Endurance test

I challenge you to watch the entire demo of Reverse engineering a Seam application from a database. Bonus points for not laughing and/or crying.

I seriously can't tell if it's a screen capture or if it was animated by hand. The pacing reminds me far too much of actually working in Eclipse.

Via In Relation To...

Changes (ch-ch-ch-ch)

A lot is going on right now. Let me bring you up to speed.

Andrea and I have decided to divorce. It was a long and difficult decision for both of us. For this and many other reasons, I will be leaving Portland on Saturday. Destination: San Francisco.

I hit the streets over the weekend to find an apartment. I can hardly believe I found a place at all, much less this beautifully restored victorian whose location couldn't be more perfect. It's in the heart of the Mission district, just around the corner from the awesome Aquarius Records and Ritual Roasters. Ritual serves Portland's own Stumptown Coffee, and does it right, so I should feel right at home.

Measure Map is still moving along nicely. I can't say any more right now but there's much to come, and being in the same room every day with Jeff and Greg will only help things.

So, it's bittersweet so say the least. I'm looking forward to a fresh start but I will miss Portland, and my friends here, a lot. Thanks to all of you.

This isn’t Typo

Thought I should mention that this site isn't using Typo anymore. It had been running on a very old, and heavily customized version which made it extremely hard to upgrade. I started looking at converting to new version with themes and felt like it was overkill. What was once little Typo has really grown into a non-trivial app.

Instead, I whipped up something really simple called Post. A short list of features..

All in 431 lines of code and 423 lines of test. Remember when this stuff was hard?

A stack of books I no longer need

So long!

Here's the stack of books I sold to Powells today. Man, that felt good.

I traded for The Work of Charles and Ray Eames, By Design and Scandanavian Design to fuel my recent interest in modern furniture and architecture.

Adding that to the recently purchased The Elements of Typographic Style and The Elements of Style (1959 printing!) gives me quite a pile of reading to do.