Jump to content

Ad Banner Module with click-through rates?


Recommended Posts

Hi Guys -

I came across something that sounds pretty basic, but haven't found a module in PW for it yet. I'd like to ask you guys if you know of something here that could solve that.


  • Ability to upload pre defined banner sizes
  • Rotate after each load of the page if more than 1
  • Present a simple click-through rate based on a period from x to y (last 30 days as default)
  • Categories with banners within (in case there are multiple sponsors) 

I've used OpenX before, but had problems with it needed to be updated VERY frequently due to possible exploits and it was a little bit of a hassle. I'm also looking for something much more simple and that runs inside the CMS.

I just wanted to throw this out there to see if anyone ever had the need for something similar and if there's any simple solution.



Link to comment
Share on other sites

It shouldn't be hard to get the whole banner rotation thing up using PW's on-board functionalty. The only additional module necessary would be AdminCustomPages to view statistics.

Here's how I'd do it:

Create a bunch of templates for category and banner as well as categories and banners templates to group them together. The category template gets a view counter which we increment with every view of a banner through the category, and we'll use that counter to pick the next banner. The banner template gets a field for the category it belongs to, one for the URL to redirect to and, of course, the image field, optionally with size settings in the field configuration. Our "normal" templates get another page field in which we pick the banner category. We also add a "click" template to store each banner click with the remote IP.

Thus we have the following templates with fields:


  • title field only

We create a banner categories page somewhere (it doesn't really matter where, can be under home).


  • title (for the category selections)
  • banner_cat_count (our counter)


  • title field only

Let's create one of these under home too.


  • title (just for us)
  • banner_image (image field, set to single image, size constraints in the field's config)
  • banner_url (fieldtype URL, the address to redirect on click)
  • banner_category (page field, single select, parent set to banner_categories page)


  • click_ip (text field)

Our pages that should include banners get a new page field (single page, NullPage if empty) page_banner_category.

Now we need two PHP templates: one to render the banner inside the page (let's name it "_banner_include.php") and one that does the counting and redirecting if a banner is clicked ("banner.php").

In banner.php, we simply add a click counter page under the banner page itself, then redirect to the configured URL:


$click = new Page();
$click->template = wire('templates')->get('click');
$click->name = 'click-' . time();
$click->parent = $page;
$click->click_ip = $_SERVER["REMOTE_ADDR"];


In _banner_include.php, we increment the view counter for the category (we could also add a counter field to the banner template and increment it on the banner page), then use the counter value modulo the number of banners in the category to get the banner itself:


$banner = next_banner($page->page_banner_category);

function next_banner($category) {
	global $pages;

	$banners = wire('pages')->find("template=banner, banner_category={$category}, include=hidden");

 	if( $banners->getTotal() == 0 ) return new NullPage();

 	$category->banner_cat_count += 1;

 	return $banners->eq($category->banner_cat_count % $banners->getTotal());

if( ! $banner instanceof NullPage ) {
	<div class="banner">
		<a href="<?= $banner->url ?>"><img src="<?= $banner->banner_image->url ?>"></a>

Now all we need in our regular pages' templates to render the banner:

<?= $page->render("_banner_include.php"); ?>

Getting an overview in the backend using AdminCustomPages should be quite easy too by just creating a custom page including a scipt that iterates over all the categories, reads the click counter, then iterates over each banner and counts the children (optionally limited by the timespan). A quick-and-dirty script (untested) to illustrate that:


foreach( wire('pages')->find("template=banner-category") as $cat ) {

	echo "<h1>{$cat->title}</h1>";
	echo "<table><thead><tr><th>Banner</th><th>clicks</th></tr></thead>\n<tbody>\n";

	foreach( wire('pages')->find("template=banner, banner_category={$cat}, sort=title") as $banner ) {
		$clicks = $banner->children->count();
		echo "<tr><td>{$banner->title}</td><td>{$clicks}</td></tr>\n";

	echo "<tr><td colspan=2>{$cat->banner_cat_count} Views / {$clicks} clicks</td></tr>\n";
	echo "</tbody>\n</table>\n";

We could, of course, make things a little easier by grouping the banners under their category, and there's nothing major speaking against it. I used a different parent for the banners to have them all under the same URL, i.e. /banners/banner-name.

All in all, it shouldn't take more than an hour to get things up and running this way.

  • Like 8
Link to comment
Share on other sites

One thing I'd like to add is considering to not use pages to store clicks (depending on the scale of the number of users). It's nice to get it up and running quickly, but in the long run a custom mysql table and raw mysql queries for the counting might be more performant. 

  • Like 1
Link to comment
Share on other sites

One thing I'd like to add is considering to not use pages to store clicks (depending on the scale of the number of users). It's nice to get it up and running quickly, but in the long run a custom mysql table and raw mysql queries for the counting might be more performant. 

Definitely. On a load heavy site and when absolute exactness of the counts is important, there's no way around using the database directly (incrementing a page field simply isn't atomic).

Link to comment
Share on other sites

I can confirm the same setup is very easy to count clicks + views...i need that for a project. Working good so far.

Only difference is that i simple count clicks and views in a integer field without additional information - so it is "data economical" and i've no problem with saved IP's and so on...

For manging the banner i use a PageTableExtended Field:


I've a general settings about the amounth of ad slots on that page - and a flag option on every single page where a user can set ads to off for a single page.

 * Adsystem show Ads in several templates
 * @var $limit (Int) set the limit of displayed ads ->look at anzeige_anzahl /settings/werbeanzeigen/
 * @var $headline (string)set the headline of the ad list

function renderAdsystem($headline = 'Anzeigenpartner') {
	//get all ad pages on basic setting - unpublished pages are not listed....
	$limit = wire('pages')->get('1056')->anzeige_anzahl;
	//build add output
	$anzeigen = wire('pages')->find("template=part_ad, limit={$limit}, sort=random");
	//render ads and collect them in $all_ads
	$all_ads = '<h4 class="subtitle">'.$headline.'<h4>';
	foreach ($anzeigen as $anzeige) {
		$anzeige->anzeige_views += 1;
		$anzeige->save(array("quiet" => true, "uncacheAll" => false));
		//get the right imagesize
		$anzeige_bild = $anzeige->anzeige_bild->size(260,120);
		//build ad link
		$all_ads .= '<a href="'.$anzeige->url.'" alt="'.$anzeige->title.'"><img class="anzeigen" src="'.$anzeige_bild->url.'" alt="'.$anzeige->title.'"></a>';
	//check if adds are off
	if ($limit == 0) {
		$out = '';
	} else {
		$out = $all_ads;
	return $out;

All is a page - so the adlink is a page for shure - and for pages we can count clicks == pageviews + redirect and views for every rendering that pageitem somewhere.

Just as an addition to the great example from BitPoet!

Thanks for that - so i'm tranquilised to find a way that a professional find, too - so it couldn't be that wrong ;)

Best regards mr-fan

  • Like 6
Link to comment
Share on other sites

  • 1 year later...


any update on this or some new modules maybe. I tried this couple of times but somehow can't get this to work at all.. I'm new to PW but I think that there should be some module for this would be much easier for beginners ike me. ;) 

I need this so that my "client" should see the clicks and other info like mr-fan image here ads.jpg


Any help is appreciated

Thank you.


Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Create New...