IMG_2069UPDATED 24th June 2013:  An update to the plugin broke this code and made me realised there was an error in it. This is now fixed in the sample code in this post.

I love Yoast’s Google Analytics and SEO plugins. Great products, frequently updated with fixes and new features, and pretty comprehensive in what they do. And FREE with pretty unintrusive donate links.

But today I found a real hole with the Google Analytics plugin’s outbound and download link tracking: it only applies to links in post content, post excerpts, nav menus, compatible widgets and comments. That’s a pretty comprehensive list of places, but if you generate links outside of these places – perhaps using post meta, as I do – then outbound or download tracking won’t be applied.

I’ve got a support request open, and until I get a response to that the following description and solution remain “in beta”!

A dangerous assumption

The problem arose because I assumed that the plugin, with download/outbound tracking enabled, would add the tracking to all links. Perhaps by using some javascript to scan the loaded page for A tags and adding the onclick event to them once the page had loaded.

But it turns out that it uses WordPress filters on various parts of the content to add the links when generating a page in PHP. The filters are added like this:

if ( ( isset( $options['trackoutbound'] ) && $options['trackoutbound'] ) ||
	                ( isset( $options['trackcrossdomain'] ) && $options['trackcrossdomain'] )
	        ) {
	                // filters alter the existing content
	                add_filter( 'the_content', array( 'GA_Filter', 'the_content' ), 99 );
	                add_filter( 'widget_text', array( 'GA_Filter', 'widget_content' ), 99 );
	                add_filter( 'the_excerpt', array( 'GA_Filter', 'the_content' ), 99 );
	                add_filter( 'comment_text', array( 'GA_Filter', 'comment_text' ), 99 );
	                add_filter( 'get_bookmarks', array( 'GA_Filter', 'bookmarks' ), 99 );
	                add_filter( 'get_comment_author_link', array( 'GA_Filter', 'comment_author_link' ), 99 );
	                add_filter( 'wp_nav_menu', array( 'GA_Filter', 'nav_menu' ), 99 );
	        }

And I’m doing something like this, which isn’t picked up by those filters:

$url = get_post_meta( get_the_ID(), '_some_meta_var', true );
printf('<a href="&quot;%s">%s</a>, $url, "My download");

After scanning the plugin’s source code, I decided that I’d try manually running the links I was generating through a function to add them. The function I created looks like this:

/*
 * It turns out that the Google Analytics for WordPress plugin that I use
 * doesn't filter ALL links. So I need to add the tracking code manually.
 * This function does that.
 *
 * $link should be a formatted HTML a tag, not just a URL.
 */
function oikos_add_yoast_ga_to_link( $link ) {
	global $yoast_ga;
	if (is_a($yoast_ga, 'GA_Filter')) {
		$link = $yoast_ga->the_content($link);
	}
	return $link;
}

And my new code for printing the links to my meta-data generated links looks like this:

$url = get_post_meta( get_the_ID(), '_some_meta_var', true );
$link = sprintf('<a href="%s">%s</a>, $url, "My download");
echo oikos_add_yoast_ga_to_link( $link );

The issue here is if Yoast change the GA_Filter class or the nature of the the_content method of that class in an update then this may stop working.

I’m hoping that my support forum post might generate a “correct” way of doing this. But for the meantime, this method is tested and works. You just need to make sure you add it wherever you need it!