PHP Paging with Caching

The majority of PHP paging script with contain a request to the database for a total row count. This is perfectly acceptable if you script needs an exact and accurate results count. However, most sites don’t need a dynamic count and the total results count represents an uneeded database request. On busier sites this effect can become quite limiting and will slow down you scripts.

As an example take a website that gets say 10 hit per second, withouit caching this represents 20 (10 hits on your database and 10 hits on your database to fecth the result set) hits per second to your database – on larger sites and larger result sets this effect is amplified. However, by simply caching the total number of rows returned you can cut the requests to your database in half.

Google uses a caching system on their results (albeit more more complicated) and they never retuirn the exact amount of results (the perforamnce hit on a site as big and busy as Google would be absolutely huge!). Instead they present results as: “results 20-40 of about 248,000″ – with figure of 248,000 coming from an estimated cache value.

To cache the number of results the script would simply store a count of the total number of records in a SESSION variable (assume the cached session value is called “totalResults”. You could also store the result as a COOKIE that expires in the future, to force an update the cached number of rows. Using sessions, the code is very simply:

if( !isset($_SESSION['totalResults']) ) {
  //Code to query your database for a row count
} else {
  //use the total record count directly from the session variable
  $myPagerObj->pageSomeData($_SESSION['total_records'], $perPage, $curPage);
}

It would also be wirth doing some validation on the cached page value, for security. However, the latter would usually be done directly in you’re paging class.

JQuery Hover Effect Image Gallery For eCommerce

web design talk jquery galleryAfter searching  for a simple jquery image gallery for an online store I decided to make my own. There were several solutions that were close to what I wanted, but quite there. The project required an simple large vierw of an image with multiple thumbnails below, when hovered upon switched the large image. The requirements were as follows: cross browser compatible (IE6 plus, Chrome and Firefox – all the major browsers), have a nice fading effect between image changes and be totally degradable if JavaScript was turned off.

First of all, take a peek and the finished JQuery image gallery – I’ve put the gallery in context on a product detail page for an ecommerce store.

JavaScript and JQuery to the Rescue!

JQuery was the JavaScript framework of choice and made it easy to get things up and running. Techniqually the same effect can be achieved without JQuery, but for simplicity I’m using JQuery. The code is quite easy to follow and I’ll just pickup  up on the main parts.

Firstly we’ll start off with the HTML – simply two dividers, with an unordered lists for the thumbnail images:

<div id="bigpic" class="b"><img src="images/big/iphone-3-big.jpg" alt="iPod Shuffle 16GB Zoom View" />
<p id="desc">iPod Shuffle 16GB Zoom View</p>

</div>

<div id="thumbs">
<ul>
	<li><a rel="images/small/iphone-1-small.jpg" href="images/big/iphone-1-big.jpg">
<img src="images/small/iphone-1-small.jpg" alt="iPod Shuffle Front View In Blue!" />
</a></li>
	<li> <a rel="images/small/iphone-2-small.jpg" href="images/big/iphone-2-big.jpg">
<img src="images/small/iphone-2-small.jpg" alt="iPod Shuffle Dual View Grey!" />
</a></li>
	<li> <a rel="images/small/iphone-3-small.jpg" href="images/big/iphone-3-big.jpg">
<img src="images/small/iphone-3-small.jpg" alt="iPod Shuffle 16GB Zoom View" />
</a></li>
</ul>
</div>

The main image is housed in the divider with the id of ‘bigpic’. I’ve also added a description below the big image – this will change when the image is hovered over to the thumbnail alternate text. Each thumbnail link goes directly to the enlarged version of the image – this way, the gallery will still work when JavaScript is turned off.

The JQuery Magic ….

Right after including the JQuery library (I recommend you make use of Google CDN for this – there are many reasons to let Google host your JQuery files) I have included an int,js file – this contains all the gallery JavaScript. The int file is a small file that catches a hover on each thumbnail and switches the main gallery image (Our ‘bigpic’ divider). All the code is contained within the mahic document.ready listener. The first half of the file catches the hover on a thumbnail:

$('#thumbs ul li a').hover(
		function() {
			var currentBigImage = $('#bigpic img').attr('src');
			var newBigImage = $(this).attr('href');
			var currentThumbSrc = $(this).attr('rel');
			switchImage(newBigImage, currentBigImage, currentThumbSrc);
		},
		function() {}
	);

Here we are getting the currentBig image href, the new big image (from our thumbs href) and current thumbnail src. The second empty fucntion is included to say ‘don’t do anything when hovering away’. Exclude this empty function and the hover event will continue to fire when you leave the image. Now we have these three variables we pass them to our switchImage function, code below:

function switchImage(imageHref, currentBigImage, currentThumbSrc) {

		var theBigImage = $('#bigpic img');

		if (imageHref != currentBigImage) {

			theBigImage.fadeOut(250, function(){
				theBigImage.attr('src', imageHref).fadeIn(250);

				var newImageDesc = $("#thumbs ul li a img[src='"+currentThumbSrc+"']").attr('alt');
				$('p#desc').empty().html(newImageDesc);
			});

		}

	}

This is quite self explanatory. The first check made is that the current big image is not the same as the target big image – if this was true we would fade in and out the same image, which leads to a rather weird looking effect. If both paths match, the user has hovered over the thumbnail of the current big image (in this case nothing would happen). Hovering over any other image will result in the current big image fading out, setting the big image src to the src from the thumbnail (the new image) and populating our description paragraph.

Using the Gallery in a Production Website

In the example 3 static large and small images have been manually added for simplicity. In a real website, maybe an online store, you would retrieve this information from a database. Another thing to note is image sizes. I always find it useful to let users upload whatever file resolution they want, giving them the exact pixels as a recomendation. To ensure that a particularly large file wouldn’t break the layout I tend to sue image resizing scripts, such as the excellent smart image resizer from shifting pixel – uploaded images can be automatically scaled to dimensions of your choosing.

Also, at some point I’ll learn about making your owns plugins for JQuery and turn this into a self contained plugin :)

There’s not a lot more to this to be honest. tested in IE6, IE7, IE8, Chrome and Firefox – all working nicely.

Take a look at the final result or download the source files. Enjoy!

Detect AJAX Requests using the x-requested-with header and xmlhttprequest

This is a small snippet of code I came across today, it allows a script to display different content based on how it was requested. This method allows your scripts to remain in a single file, handing both AJAX and normal requests – it avoids ending up with lots of small PHP files in your AJAX folder, that deals with ajax requests.Another use would be a page that has 2 web forms, one AJAX and one normal. You could keep the code for this page in a single file. This method is also useful for security purposes, as it would ensure that requests to your AJAX scripts are via AJAX only. It also has uses for writing unobtrusive JavaScript – maybe ensuring that an AJAX enabled web form would work when javascript is disbaled.

For example, the below code would display different code depending on if the request for the page was made via AJAX or directly via a browser.

if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    //This is an AJAX request, do AJAX specific stuff
}
else {
    //This is not an AJAX request E.g. display normal page content.
}

In some code I was working on today, I saw a neater way of achieving the above, this would be included in your common config file:

define('IS_AJAX_REQUEST', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');

if(IS_AJAX_REQUEST) {
    //This is an AJAX request, do AJAX specific stuff
}
else {
    //This is not an AJAX request E.g. display normal page content.
}

There’s an HTTP variable set called HTTP_X_REQUESTED_WITH, which will is set to ‘XMLHttpRequest‘ if the request method is via AJAX. This is method is untested with JavaScript frameworks other than JQuery, so may not work (but I don’t see any reason at all why it wouldn’t!).

It’s also worth noting that not all web servers include this variable and sometimes omit this specific $_SERVER paramter. Use vardump($_SERVER) to check that the HTTP_X_REQUESTED_WITH is present.

Displaying a Breadcrumb Navigation for Multiple Sub Categories via PHP

While making an ecommerce store I ran into the issue of displaying a category breadcrumb. Usually this is easy as I always recommend keeping the numbers of categories and sub categories to a maximum of 1 level deep. E.g. Tshirts > Red tshirts. For this store, due to the sheer number of products the owner wanted to add up to seven category levels. While there are many tutorials on this floating about, they all seem tocus on displaying the whole tree – very useful for a sitemap page, but not a breadcrumb navigation. While it would have been possible to hard code several if statements into the category listing page, this seemed a bit messey and would cause problems if an eighth level was added.

For the breadcrumb naviagtion I needed a function to displaying the path to a given category ID, sometimes refered to as a single branch or node. I was using a simple parent child database table structure:

php multiple=

While the latter may seem fairly trival I really couldn’t get my head around the problem. After a bit of Googling, I found a function that was a good starting point so adapted it to fit my problem (the function is part of a categoru class):

function getCategoryTreeIDs($catID) {
		$row = DB::getInstance()->query("SELECT parent FROM categories WHERE ID = '$catID'")->fetch();
		$path = array();
		if (!$row['parent'] == '') {
			$path[] = $row['parent'];
			$path = array_merge($this->getCategoryTreeIDs($row['parent']), $path);
		}
		return $path;
	}

The function simply returns an array of category IDs. E.g 20, 28. So from the array I’d know that the tree would go as Home > Cat ID 20 > Cat ID 28.

Displaying the Breadcrumb Navigation

To display the actual breadcrumb I simply added the following method, that loops through the array of ID we just generated. The getNameLink method simply generates an SEO feindly website URL for the category, inside the <a> tag.

function showCatBreadCrumb($catID) {

		$array = $this->getCategoryTreeIDs($catID);

		$numItems = count($array);
		for ($i = 0; $i<=$numItems-1; $i++) {
			echo $this->getNameLink($array[$i]) . ' &raquo; ';
		}
	}

The result is a nicely formatted breadcrumb (to use our tshiorts example again):

Home &rquao; Clothes &rquao; tshirts &rquao; Mens &rquao; Red tshirts &rquao; Offensive &rquao;

A recursive function inside a loop, are you insane?

Some of you may have noticed that the function used to generate the category IDs is called recursively. This generally considered bad practice, for large data sets due to performance issues. However, for the current use this isn’t an issue. I know for a fact that client won’t be adding categories more than several levels deep, so performance really isn’t an issue in my eyes here. Maybe if we had hundreds of categories, but for several it’s really a non issue in my opinion.

getCategoryTreeIDs

Enhanced Visitor Event Tracking With Google Analytics and JQuery

Google Analytics has fast become the industry standard to track a plethora of web based information about your website. Whilst being totally free and easy to setup, you are limited to tracking elements that physically render in the browser – so items such as PDF, ZIP and RSS feeds links are not tracked, this because Google Analytics has a great reliance upon JavaScript. However, tracking such links can be achieved with a small amount of extra work.

Personally, I wasn’t aware you could track specific links with Analytics and only ever considored this when a client asked ‘why doesn’t Google show me the numbers of times my marketing report (read: a PDF file) has been clicked?’ – a totally valid request that I wanted to investigate.

Use JQuery to improve Google Analytics and track downloads, RSS, Email & external links

First things first, make sure you have a google Analytics account, the latest version of JQuery and the latest version of the analytics code running on your website :)

As with the majority of the JQuery magic, everything happens within the doc ready event listener – this will used to capture various clicks to select elements.

Tracking Download Link Clicks (PDF, ZIPs etc.)

$(document).ready(function() {
	
	$("a[rel=download]").click( function() {
		var fileName = $(this).attr("href");
		pageTracker._trackPageview(fileName);
		return true;
	});

});

Then on every link you wish to track, simply add the rel attribute to your non HTML files as follows:

<a href="myData.zip" rel="download">Download My ZIP Data File</a>

Tracking Downloads of Specifc File Types (E.g. PDF files)

Using the dollar sign to match against links that end in .pdf (or any extension you wish to track).

$(document).ready(function() {

	$("a[href$=pdf]").click( function() {
		var myPDF = "/pdfDownloads/" . $(this).attr("href");
		pageTracker._trackPageview(myPDF);
		return true;
	});

});

The /pdfDownloads/ is used to identify and seperate report data within Google Analytics.

Tracking the click of a specific link such as an RSS feed

Simply add an identifier to your RSS feed link (in this example the link was given an id of ‘rssFeed’):

$(document).ready(function() {
	
	$("a#rssFeed").click( function() {
		pageTracker._trackEvent("RSS", "RSS Subscriber Link Clicked");
		return true;
	});

});

Tracking mailto: Link Clicks

$(document).ready(function() {
	
	$("a[href^=mailto:]").click( function() {
		pageTracker._trackEvent("Mail", "User clicked on mailto link");
		return true;
	});

});

Tidying up….

You should also disable the clicked element to prevent multiple event recording and provide feedback. To do this, simple add the following at the start of each piece of code – disbabling the element and changing the cursor to an egg timer (although you could display a small graphic to make things look prettier):

$(this).css("cursor", "wait");
$(this).attr("disabled", true);

Prevent Duplicate Content using the Canonical Url Tag

I was recently doing an seo audit of a small ecommerce website. One of the first things I did was to do a ‘site:www.domain.com’ in Google. Amazingly, the site in question has approximately 8200 pages indexed in Google. This was quite surprising when the store only sold less than 1500 unique products. The site used a horrible ecommerce module bolted onto phpnuke and has a horrible url structure, appending lots on unecessary querystring data onto the url.

Whilst looking through the Google results for this site the majority of pages were as follows:

/index.php?tab=123&txtSearch=ALL&List=oasc&Sort=PName%2CPName&CreatedUserID=1&pageindex=40&Language=en-GB

The site has an advanced search page, whereby you can sort products using a variety of options such as ascending order, descending order, size, price etc. This is bad for a number reasons, but mainly due to duplicate content (not to mention lower serps ranking, traffic loss and decreased page relevancy) . A page of results in ascending and descending order is essentially the same page, simply a different view of your data – you can help search engines via using the relatively new canonical url link tag.

To illustrate I’ll use an example of a typical category page, whereby you can sort a list of products in ascending and descending order, leaving you with a number of urls as follows:


http://www.shop.com/category.php?catName=Shirts&sortOrder=ASC

In this example the part of the querystring creating the duplicate content would be the sortOrder parameter – as you would want your seperate categories indexed.

The solution is quite simple. In your head tag add the following:

<link rel="canonical" href="http://www.shop.com/category.php?catName=Shirts" />

By adding this to your category page you are telling search engines (currently Google, Yahoo, Ask and Bing use this tag) that this page is a copy of http://www.shop.com/category.php?catName=Shirts. Indicators such as Google Pagerank are also transferred to your preferred url.

The canonical url tag has many uses and can be used to help with the following issues:

  • Pages that contain session IDs appended to the querystring
  • Search results pages that append search data to the querystring
  • Print versions of page
  • Duplicate content for www. and non-www. pages 0 in your canonical tag you would include your preferred url
  • Same content contained in multiple categories – E.g. a product contained in multiple categories on an online store
  • Removing affiliate ids in the url
  • Preventing multiple pages of a discussion topic with comments from being indexed E.g. shop.com/post.php?id=123&page=1

You can read more about the canonical tag at the official Google Webmaster Blog. Matt Cutt’s also has a 20 minute video explaing the canonical tag in more depth.

The main point to consider is that the canonical tag is simply a hint and not a directive. It is another method to give search engines help in indexing your content. This is very useful when working on existing sites already indexed by Google. However, on new sites bit more planning can help. For instance, in a  previous article I covered 301 redirects for seo using htaccess – how to set a prefferred version of your site via htaccess. On an ecommerce store you could avoid appending search data to the querystring.

EDIT: wordpress and all in one seo plugin generate canonical link tags for blog posts. For example, comments are seperated into multiple pages E.g


http://www.web-design-talk.co.uk/157/how-to-deal-with-difficult-clients-using-split-testing/comment-page-1/#comment-344

With the actual content being at:


http://www.web-design-talk.co.uk/157/how-to-deal-with-difficult-clients-using-split-testing

If you have a quick look at the source code to the comments page you’ll see the following has been added:

<pre id="line34"><link rel="canonical" href="http://www.web-design-talk.co.uk/157/how-to-deal-with-difficult-clients-using-split-testing/" />

How to Deal With Difficult Clients Using Split Testing

Sometimes you can be in the process of trying to tell a client that their idea simply won’t work. Be it a flimsey campaign idea of extra design element that you know through experience will not work and produce the desired KPIs for a client project. You can even show the client links, articles and examples of why their idea will fail to deliver results. However, if this is potential or existing client they are likely to go elsewhere, to a company willing to follow their every word without consideration – I have come across web companies who will do this.

Recently an existing client came to me asking why his site isn’t showing up when people search for a particular long tail search term. Now, his existing site used a pretty awful content management system that didn’t even allow him to set his own pages titles or meta descriptions. Furthermore, he was lacking inbound links, which people ranked above him did have. This all sounds simple and straightforward but even after I had explained (in quite clear and non technical langauge may I add) the merits of good SEO and one page content the client simply wouldn’t accept this as a solution. He had his own short term and less costly solutions – basically revolving around the the idea me resubmitting his sitemap page to all the major search engines each day. I’m not debating that submitting a sitemap isn’t a good idea, because it is. However, the client’s main KPI for this project was increased site enquiries.

After much discussing this we had both come to a bit of an awkward silence – not a good thing if you’ve ever experinced this in client meetings. For some reason I remebered back to my unoversity days where I had read something about split testing (or A/B testing) – where you can turn a negative situation into a positive one.This is quite a delicate situation to be in as it can damage your client relationship quite quickly.

The idea was to use the client’s idea for a period of time and my idea for a period of time. At the start of this I would install Google Analytics (I was tempted to use Google’s website optimizer, but decided against it) and let the statisitics do the talking – as a no one can argue with statistics.

This method has been very useful previously when demonstrating the merits of creating a dedicated landing page for Google Adword campaigns, but can be used anywhere if you’re willing to a little bit extra.

This method is beneficial for the following reasons:

  • The client’s idea are being dismissed as wrong (however right you think you are)
  • You are showing the client that you care enough to demonstrate your ideas
  • Occassionaly the client will back down as soon as you explain your plan of attack
  • It prevents those awful awkward silences
  • You have a real world example to use in your other client meetings
  • You are speaking the clients language in that you are demonstrating how your actions lead to increased conversions
  • You are being direct, which I personally think is alwasy a good thing – as such statistics are often a huge eye opener for clients
  • If and when the client comes to the same conslusion as you, they won’t blame you

There is always the arguement that the client is the client and that it’s all business at the end of the day. However, I personally pride myself on doing things properly. Others will say just get on with, do what the client wants and forget about it – you can only offer your opinion. This is a good point but can still damage your client relationships when they return later on and you need to charge them again. It all depends if you require long or short term client relationships – as they are definately an investment.

Improve SEO Through Home Menu Anchor Text Optimisation

seo-anchor-textIt’s a widely known fact that link anchor text is rated YH2Z675VXTC5 highly by search engines and is often the deciding factor in your SERP position for competitive terms, mainly because it gives meaningful information to users (amongst others). Correct use of anchor text (on both inbound and outbound links) will give your page increased meaning.

I’m sure you use this fact throughout your website while performing onsite SEO. Any tutorial will rightly tell you that keyword relevancy is of upmost importance here. However, a lot of the time you end up with a ‘Home’ link on your menu, linking to your main page.

This is bad for SEO for a number reasons. Firstly, the anchor text ‘home’ is very poor choice of word to use as it’s meaning is highly diluted nowadays. Now unless you have a site relating to homes, the keyword isn’t very useful at all, as we don’t want to rank highly for the term ‘home’. However, at the same time users are familiar with such a link and it makes sense to name such a link to your main page. The situation is worsened if your site is large with a great number of internal links. Imagine having a 100 page site, all with the anchor text ‘home’ – this is a lot of inbound links telling search engines each page is related to ‘home’! Furthermore, the menu link’s are usually towards to the top of the page, giving them inscreased relevancy to search engines.

The solution is a compromise, use ‘home’ along with you main keyword(s) – making sure to avoid obvious stop words like ‘and’. For example ‘Graphic Design Home’. Even better use your main keyword directly in the anchor text i.e. ‘Graphic Design’. This is quite a powerful and simple SEO trick that is easy to implement into your site.

Process Custom eCommerce data using Paypal IPN

More often than not it’s hard to visualise how you can send custom information to Paypal during checkout. The list of available hidden field variables initially seems very specific and restrictive at best. Granted, you can easily send over simple things such as your shipping amountm and tax rate. However, during order processing (done in you IPN script that Paypal sends the transaction’s IPN post data to) you often want to record more information when creating and storingn order information.

For example, let’s say the user can enter a specific coupon code during checkout. You would want to make sure the Paypal transaction has been successful before making the voucher as used, to do this you would need to know what code was entered during checkout. In the following simple example we’ll use the ‘custom’ field variable  – this is an optional field, whereby the the data is never presented to the shopper and can be 256 character long. Whatever is placed in this field before clicking your checkout button will be invisibly sent ot Paypal and posted back to your IPN script (assuming you have youre ‘rm’ or return method set to 2, or ‘POST’). The HTML for the hidden field is very simple:

<input type="hidden" name="custom" value="YOUR CUSTOM INFORMATION HERE">

Now, let’s say when you’re recording all the order information you weant to record the exact coupon code, delivery method id, the method by which the customer found your site (E.g. another id) and referrer id number. For convenience and for the sake of the example, I’ll assume you’ve done all the necessary processing to get your four pieces of information. The code to create our hidden field data is as follows:

/* ...logic to get below variables here! */

$shipping_method_id = '33';
$coupon_code = '45895';
$found_out_method = '9';
$referrer_id = '200';

$custom_info =
                       array(
			'shipping_method_id' => 33,
			'coupon_code'=> 45895 ,
			'found_out_method' => 20 ,
			'referrer_id' => 9
			);

/* Initiase field data and looping variable */
$field_data = NULL;
$i = 0;

/* Loop through info array to build data string */
foreach ($custom_info as $key => $field) {

	$field_data .= $field;
	$i++;

	if ( $i !== count($custom_info)) {
	      $field_data .= '-';
	}

}

/* create the hidden field
generated HTML is <input type="hidden" name="custom" value="33-45895-20-9"> */
echo '<input type="hidden" name="custom" value="'.$field_data.'">' . "\n";

Printing the value of $field data will give you the string ’33-45895-20-9′. This translates to shipping method id 33, coupon code 45895, found out id 20 and referrer id 9. The dash symbol has been used to delimit values for convenience, as we need to split this string up later on.

To process these variables in your IPN script (see the Paypal PHP sample script) you simply use PHP’s explode method to split the data into an array:

/* $_POST['custom'] contains the custom information we initially sent to Paypal */
$data = explode('-',$_POST['custom']);

/* Convert $data array into variables for further processing */
$shipping_method_id = $data[0];
$coupon_code = $data[1];
$found_out_method = $data[2];
$referrer_id = $data[3];

So you’ve now posted a string of custom information to Paypal and got this custom data back via IPN during the transaction processing. Now you have assigned each piece iof the array to a variable, you can easily continue to create your order header and save it to a database.

Tracking Twitter Performance Using Google Analytics

If you use the ever popular twitter there’s a high chance you’ll be linking to your company webiste or personal blog in your tweets or profile link. As the aim is use twitter as a marketing tool to drive traffic, you can use Google Analytics to track the link you placed the twitter profile – just like an email campiagn or PPC advert

If you use Twitter as a marketing tool to drive traffic to your site then you should treat it in exactly the same way as you would a newsletter, a PPC advert or a banner and track each Tweet’s performance beyond simple click data. How many visits do you get, how long do they stay on your site, how deep do they go, what is the bounce rate like and how much revenue do they generate?

The benefit to ‘tagging’ this link is that Google Analytics will record more than use basic click data – you can record a whole host of advanced user data such as how they navigate your site and length of visit. By default Google will track such links, but traffic from services such as bit.ly will be dumped into the direct traffic area of Google Analytics. The steps to get the latter up and running are quite simple:

1: Go to Google’s URL builder to generate an url . Enter the following information:

Website URL: your website address

Campaign Source: enter a relevant source here to identify your campaign E.g. twitter

Campaign Name: enter a name used to identify the campaign, this is used to identify the campaign in Google Anlytics E.g. twittertracking

2: Click generate URL and something similar to the following will be created: http://www.web-design-talk.co.uk/?utm_source=twitter&utm_medium=social&utm_campaign=twittertrack


3: If posting to twitter you can paste this URL directly in the tweet box, as twitter will automatically shorten this url.

4: After approximately 24 hours data will appear in your analytics account. Simply navigate to Traffic Sources. If you’ve used the same terms to build the url as above you’ll see an entry called ‘twitter / social’. You can also view information by navigating to Traffic Sources > Campaigns where you can click the campiagn name (‘twittertrack’ was used in he example above).

Google Analytics Once Tracking is Installed

Google Analytics Once Tracking is Installed