Advertising is one of those "necessary evils" of the web, and of non-ecommerce blogs in particular. For blogs which aren't associated with a particular product or revenue-generating business, advertising is the main way to pay the bills. It's not something which generally enhances a site, but we try our hardest to ensure that it's not actively detracting from the important bits of a site.

openx-adblocks.jpg

One thing which can seriously detract is the increased load time when a site is filled with ads. This not only comes from the actual images and other assets which are loaded for each ad block, but often those blocks are generated by chunks of javascript, which can add rather a large amount of code to the HTML page, even before any imagery is loaded.

Most blogs start out with Google's Adsense, and then eventually graduate to Ad Manager if there's enough advertiser interest that they can start selling their inventory directly. However, Google does have some vast shortcomings, so when your sites get big enough, you start looking around for ad-serving alternatives, and inevitably come upon OpenX.

The Standard Way of Calling Ads

We're about to launch a redesign for a fantastic australian blog (more on that soon), who have a sizable roster of advertisers. They can have over 20 ad blocks of various sizes on some of their pages, so using "traditional" OpenX ad calls was not only time-consuming to add to the site, but it was adding a huge amount of HTML weight. Here's what the "standard" OpenX ad block code looks like:

<!--/* OpenX Javascript Tag v2.8.1 */-->
<script type='text/javascript'><!--//<![CDATA[
   var m3_u = (location.protocol=='https:'?'https://example.com/www/delivery/ajs.php':'http://example.com/www/delivery/ajs.php');
   var m3_r = Math.floor(Math.random()*99999999999);
   if (!document.MAX_used) document.MAX_used = ',';
   document.write ("<scr"+"ipt type='text/javascript' src='"+m3_u);
   document.write ("?zoneid=11");
   document.write ('&amp;cb=' + m3_r);
   if (document.MAX_used != ',') document.write ("&amp;exclude=" + document.MAX_used);
   document.write (document.charset ? '&amp;charset='+document.charset : (document.characterSet ? '&amp;charset='+document.characterSet : ''));
   document.write ("&amp;loc=" + escape(window.location));
   if (document.referrer) document.write ("&amp;referer=" + escape(document.referrer));
   if (document.context) document.write ("&context=" + escape(document.context));
   if (document.mmm_fo) document.write ("&amp;mmm_fo=1");
   document.write ("'><\/scr"+"ipt>");
//]]>--></script><noscript><a href='http://example.com/www/delivery/ck.php?n=a86ff4c4&amp;cb=INSERT_RANDOM_NUMBER_HERE' target='_blank'><img src='http://example.com/www/delivery/avw.php?zoneid=11&amp;cb=INSERT_RANDOM_NUMBER_HERE&amp;n=a86ff4c4' border='0' alt='' /></a></noscript>

It's a bit messy, but not so bad by itself. However, when you've got 8 of these blocks all together, and another dozen spread across the rest of the page, it gets rather hefty. The front page of the site in question, without ads, weighs in at a bit over 600 lines of HTML. Dropping in 20 ad blocks brings it up to just under 1000 lines.

As I said. Hefty.

Making OpenX Faster and Smoother

Fortunately, OpenX has an invocation method called Single Page Call, which is designed to make the whole setup much more svelte. So instead of calling that gargantuan chunk of javascript and .write methods over and over, you have a single invocation script called in the header:

<script type='text/javascript' src='http://example.com/www/delivery/spcjs.php?id=1'></script>

... and then a much smaller, sexier invocation code for each ad block:

<script type='text/javascript'><!--// <![CDATA[
/* [id1] Wide Ad - Top */
OA_show(1);
// ]]> --></script><noscript><a target='_blank' href='http://example.com/www/delivery/ck.php?n=c8acc6c'><img border='0' alt='' src='http://example.com/www/delivery/avw.php?zoneid=1&amp;n=c8acc6c' /></a></noscript>

Switching to this method decreased our page size by 30%! Fantastic.

The only limitation here is that it expects every ad zone you're calling to be unique. So you can't make a single zone called "interpost_ad" and call it 10 times, it wants you to create 10 different zones called interpost_1 - interpost_10, and set them all up individually. This is a monstrous pain in the butt for administration and development, doubly-so because what I'd read in the OpenX docs had me expecting that this setup would allow different banners to be called if the same zone was repeated.

The way to actually achieve this is hidden down the bottom of the Single Page Call documentation page under "Advanced Usage". I'd never got that far down, because I thought I had the code working correctly and that my delivery problems were due to backend mis-configuration.

To get unique ads showing up in repeated zones, you have to create a "zone array" which sits above your invocation call in the header, and associates particular ad block IDs with invocation zones in the page.

<script type='text/javascript'><!--// <![CDATA[
var OA_zones = {
'ad_top' : 22,
'sidebar_mrec' : 17,
'selfpromo_1' : 18,
'selfpromo_2' : 19,
'sideblock_1' : 21,
'sideblock_2' : 23,
'sideblock_3' : 23,
'sideblock_4' : 23
}
// ]]> --></script>
<script type='text/javascript' src='http://example.com/delivery/spcjs.php'></script>

Then you just change those "single page call" invocation codes to include the correct zone name:

<script type='text/javascript'><!--// <![CDATA[
    /* Sideblock 1 */
    OA_show('sideblock_1');
// ]]> --></script>
<script type='text/javascript'><!--// <![CDATA[
    /* Sideblock 2 */
    OA_show('sideblock_2');
// ]]> --></script>

... etc.

This works beautifully, because it allows you to quickly tweak which zones are being delivered to which areas of the page from a single point in the header, rather than having to make edits all over the place when you want to swap things around. You still need each ad zone in the page body to have a unique name though, which is fine for headers, sidebars, and footers, but how do you manage it for dynamically generated sections of the site? Your search results, tag and category archives?

The old way to do this in Wordpress would be to make a "count" variable in PHP, and have it iterate each time the loop was called. Usually that looked something like this:

<?php if (have_posts()) : ?>  
<?php $count = 0; ?>  
<?php while (have_posts()) : the_post(); ?>  
<?php $count++; ?>  
  <?php if ($count == 1) : ?>  
          //bunch of ad code goes here
  <?php if ($count == 2) : ?>  
          //bunch of ad code goes here
  <?php if ($count == 3) : ?>  
          //bunch of ad code goes here
   <?php else : ?>  

  <?php endif; ?>  
<?php endwhile; ?>  
<?php endif; ?>  

This is a pretty reasonable solution, but that counter loop can be salted across a broad swathe of code, as counters are often used for a couple of things for each post called on a page. So the initial $count call would be at the top of the php page, then your actual invocation code statements came much later. Rather confusing stuff.

Fortunately, Wordpress 2.7 introduced a WP_Query function variable called "$current_post", which gives you the numeric ID of the current post in the loop. No more counter code required!

Using Wordpress' $current_post Property To Create Dynamic Ad Blocks

$current_post is the final ingredient required to give us light, automatically generated ad blocks. Current_post is called from the WP_Query function, like so:

<?php echo $wp_query->current_post; ?>

That would echo the ID of the current post in the loop. Of course keeping in mind that the data is coming from an array, so the first ID will be 0.

Remember our super simple ad block javascript call?

<script type='text/javascript'><!--// <![CDATA[
    /* Sideblock 1 */
    OA_show('sideblock_1');
// ]]> --></script>

Because this is javascript, we can use PHP to dynamically re-write the code on page load. Using $current_post, we can have it write the post ID each time the Wordpress loop is run, giving us as many unique ad blocks as we have posts on the page. Here's how it looks:

<script type='text/javascript'><!--// <![CDATA[
OA_show('interpost_<?php echo $wp_query->current_post; ?>');
// ]]> --></script>

That will call an ad zone called "interpost_0" on the first loop, then "interpost_1" etc. for as many posts as appear on the page. Then you just need to add those zones into your zone array in the header, which now looks like this:

<script type='text/javascript'><!--// <![CDATA[
var OA_zones = {
'ad_top' : 22,
'interpost_0' : 20,
'interpost_1' : 20,
'interpost_2' : 20,
'interpost_3' : 20,
'interpost_4' : 20,
'interpost_5' : 20,
'interpost_6' : 20,
'interpost_7' : 20,
'interpost_8' : 20,
'interpost_9' : 20,
'interpost_10' : 20,
'interpost_11' : 20,
'sidebar_mrec' : 17,
'selfpromo_1' : 18,
'selfpromo_2' : 19,
'sideblock_1' : 21,
'sideblock_2' : 23,
'sideblock_3' : 23,
'sideblock_4' : 23,
'sideblock_5' : 23,
'sideblock_6' : 23,
'sideblock_7' : 23,
'sideblock_8' : 23
}
// ]]> --></script>
<script type='text/javascript' src='http://advertisers.babyology.com.au/www/delivery/spcjs.php?id=1'></script>

It's a super simple method, saves a load of programming, and keeps your code readable and futureproof.

Yay for $current_post!