Advertisement deprecated

AppSuite features a basic framework to help implementing ads for monetization. Usually code snippets generated by some advertisment provider is meant to be used on static web sites. Integrating it into a web application might not be straight forward. That's why this framework has been created. It defines some common areas (ad spaces) to serve banners in different forms, it provides an API to refresh those banners on different events (e.g. app change, some timeout, …), and it helps to integrate the code snippets needed to actually run the campaigns by the provider.

Configuration

Configuration for the io.ox/ads framework must be provided by a plugin in the namespace io.ox/ads.

All registered plugins for io.ox/ads will get loaded and the return values of their modules will be handed as parameters for invocation of the inject method (with this being bound to $('head')) as well as the config method of the extension point io.ox/ads. It is therefore possible to customize this functionality by extending io.ox/ads.

When using the default implementation, custom modules should return an object containing two keys:

  • inject - a String with valid HTML code which is to be appended to the head element
  • config - the configuration is simply stored internally

The config object can contain arbitrary data. The changeModule method of the io.ox/ads extension point will be invoked with the app name as first parameter and a Baton containing a reference to the app and the config object.

The default implementation expects the config object to contain one key for each space. Values for these keys used in the default implementation should be an object defining:

  • space - a String which defines the desired target space for this ad
  • html - a String which is appended to the corresponding space
  • reloadAfter - a number value, representing the time until the next refresh operation for an area is invoked
  • showInModules - falsy value (always active) OR an array with app names to match against (e.g. 'io.ox/mail', …)
  • capabilities - falsy value (always active) OR a string to be passed to capabilities.has method (e.g. 'webmail && !alone')
  • active - false deactivates this ad, every other value means it's active

For every defined area, the cleanup method of the corresponding extension point will be invoked. Active spaces are determined by filtering using showInModules and capabilities options in the area configuration. For every active area, the draw method of the extension point will be invoked. (See Spaces section) The reload method of the area extension point will be invoked in a regular interval defined by the value of reloadAfter. The configuration object will be passed to each method invocation.

Spaces

There is a list of extension points defined, which can be used to place banners. All points share a similar API:

ext.point('the/spaces/name').extend({
    cleanup: function (baton) { /* do some cleanup */ },
    draw: function (baton) { /* append baton.data.html to the spaces element, do other stuff */ },
    reload: function (baton) { /* trigger a reload of the banner */ }
});

The following ad spaces are pre-defined and can be used to serve ads:

  • io.ox/ads/leaderboard
  • io.ox/ads/skyscraper
  • io.ox/ads/skyscraperLeft
  • io.ox/ads/mailDetail
  • io.ox/ads/driveFolder
  • io.ox/ads/portalBillboard
  • io.ox/ads/mailSentOverlay

In order to activate one of these spaces, a custom plugin is needed, shipping a configuration as described above.

Utility API

Most ad campaigns share common needs regarding functionality. The io.ox/ads framework provides a set of tools to simplify custom implementations.

Cooldown

Sometimes, there are events that should trigger a reload of ad banners, but should not do so too frequently. You want an ad space to cool down a certain amount of time, before a reload is actually triggered. That's where Cooldown timers come in handy.

To use those timers, a new instance of the Cooldown util class is needed:

var config = loadConfig(); // the current list of configured ads
var Cooldown = require('io.ox/ads/util').Cooldown;
var cooldown = new Cooldown(config);

The instance can then be used like this:

ext.point('io.ox/ads/leaderboard').extend({
    reload: function (baton) {
        cooldown.touch(baton.data.id).then(function () {
            // do the refresh, only called if space is "cool"
        }, function () {
            // ad space is too hot, did not refresh, but may be collect some metrics?
        });
    }
});

// reset cooldown timer for third banner in configuration
var id = 2;
cooldown.reset(id);

// reset all cooldown timers
cooldown.reset();

Customization

The default behavior can be completely customized using well-known methods, extension points. Despite the special points for the spaces as described above, it is possible to extend the general point io.ox/ads. The API for this point looks like this:

ext.point('io.ox/ads').extend({
    changeModule: function (baton) { /* do something if user opens a new app/module */ },
    config: function (baton) { /* do something with the configuration */ },
    inject: function (baton) { /* inject the global JS from ad provider, this variable is bound to $('head') */ }
});

As a reference implementation and a starting point, this project can be used. The implementation is used to demonstrate the integration of a few spaces using a little more than just a minimal configuration.

Incompatible changes since 7.8.1 release

Change of the configuration structure

In order to support multiple banners per ad space, the configuration is now an array of "ads", instead of an object providing the configuration for each space. To define the target space, the space attribute needs to be set for each ad configuration.

Example:

// old:
{"io.ox/ads/leaderboard": {
    "html": "<div>yay, here's a banner on the top of the page!</div>",
    "reloadAfter": 30000
}}

// new:
[{
    "space": "io.ox/ads/leaderboard",
    "html": "<div>yay, here's a banner on the top of the page!</div>",
    "reloadAfter": 30000
}]

Code removed from Core UI repo/package

The code has been moved into a separate plugin, that needs to be installed additionally if this feature is needed. However, development and API is still maintained by the Core UI team.