Adding an advertising block to a web site might seem like a simple task, but some types of website caching can make it more difficult to implement. To share an example, one of our clients needed to have an advertising block, with ads showing on a percentage of the time basis and to not have it cached by the reverse proxy server - Varnish.

  • The objective: I have a simple advertising block where I'd like to display one ad 60% of the time and the other ad 40% of the time.

  • The problem: It seems that Varnish is caching the block so a single ad is displayed 100% of the time.

The ad blocks are built using the nodequeue and views modules. The nodequeue has space for ten items. Each ad is added the number of times needed to match the percentage it should display on the page. The view is set to randomly pick an item from the nodequeue.

It seemed everything was set up properly for displaying each ad in the 10% buckets, but the ads did not seem to rotate as they should. Come to find out, a page hit in Varnish included the ad block.

If you are not familiar with "Varnish", it is an HTTP accelerator designed for content-heavy dynamic web sites as well as heavily consumed APIs. At a very basic and high-level overview of what it does, it functions as another sort of caching system which serves to reduce the load on your webserver. But as we see here, if not managed properly it can provoke the unintended side-effect of preventing some dynamic content from being rendered appropriately.

Loading Content Outside Normal Page Rendering

The solution for the problem we have is to load the ad block dynamically outside of the main page loading sequence. Typically, this kind of workflow is going to use Ajax. If you're not familiar with the web development concept of Ajax, it is a kind of acronym that is short for asynchronous JavaScript and XML. The follow steps are an overview of how one would proceed with implementing the proposed solution:

  • On the php side, we created a menu hook and page callback to load the views html output and return the output to the browser when called upon.
  • In the frontend, we setup an ajax call using jQuery. When the page is fully loaded, a call is made to the server, the html output is returned and placed inside an empty element waiting as part of the normal page load.
  • In Varnish, the ajax path was excluded from being cached.

The steps illustrated above are how we tackled this problem, and the solution has been in place for our client for a while now. It isn't overly complex and works great!