Skip to content

Instantly share code, notes, and snippets.

@JasonStoltz
Created November 21, 2013 13:20
Show Gist options
  • Save JasonStoltz/7581461 to your computer and use it in GitHub Desktop.
Save JasonStoltz/7581461 to your computer and use it in GitHub Desktop.
A wrapper for Test & Target to turn its "over-simplified-for-marketers" mbox api into a developer friendly, JSONP-like service call.
/**
*
* Adobe Test and Target doesn't really have a nice API for dynamically including content, so this wraps it to provide that.
*
* What T&T wants you to do is simply define an "mbox" div on a page, call them and tell them the id of that div, and they handle
* populating content to that div.
*
* What I prefer to do is simply make a service call to T&T, have them give me some data/configuration back, and I will handle rendering
* content, however I see fit.
*
*/
window.experience = (function(){
'use strict';
var experience = {
/**
* This is the only public method that site code should need to deal with. Wrapper around mboxUpdate that does the following:
*
* 1) Returns a promise
* 2) Handles calling of mboxDefine, so it is not a seperate step
*
* @param {String} Mbox name
* @param {String...} Any number of string values that look like "route_distance=399"
* @return {Promise} A promise that will be resolved with JSON response from Test and Target
*/
load: function() {
var args = Array.prototype.slice.call(arguments, 0);
var mboxName = args[0];
var $mbox = this.mboxes[mboxName];
/*T&T needs to have an div to render the returned content to ... we are creating them dynamically as they're needed,
rather than placing on the page staticly*/
if (!$mbox) {
$mbox = $('<div id="' + mboxName + '">');
$('body').append($mbox);
this.mboxes[mboxName] = $mbox;
mboxDefine(mboxName, mboxName);
}
/*Because mbox.js gives us no real way of knowing when the request is done, we're a using JSONP-like strategy.
We create a unique id like "OTA_WIDGET_1_MBOX12312314" and pass along as an "mbox parameter" on our T&T call.
The content we configure in T&T is actually JSON wrapped in a function call to the "resolve" function defined
in this file (JSONP):
<script>
experience.resolve("OTA_WIDGET_1_MBOX12312314", {JSON here})
</script>
Our script knows which promise to resolve based on that unique id: "OTA_WIDGET_1_MBOX12312314"*/
var callbackid = mboxName + new Date().getTime();
var deferred = jQuery.Deferred();
this.deferreds[callbackid] = deferred;
args.push('callbackid=' + callbackid);
/*Just want to make sure this happens after our promise is created, because we want to make sure all
callbacks are in place when T&T returns*/
setTimeout(function(){
mboxUpdate.apply(this, args);
});
return deferred.promise();
},
/**
* Response from T&T needs to call this in order to resolve the promise. So this call will actually be located
* in T&T content.
*
* @param {String} callbackid id that was passed to T&T that corresponds to experience.load call
* @param {Object} json response
*/
resolve: function(callbackid, options) {
this.deferreds[callbackid].resolve(options);
delete this.deferreds[callbackid]; //Don't hold on to a reference
},
deferreds: {},
mboxes: {}
};
return experience;
})();
@saalmaan
Copy link

@JasonStoltz Neat little trick, I was looking for something like this and seems like I can use this to write ur A/B test with much more flexibility now. I am very new T&T (coming from maximiser background), so little confused as to how to get the mbox JSON data. Can you explain this gist with an example from T&T. An example can be that on a page we want to change a div (id=test1) with new content, so what piece of code goes in T&T and what goes on the page? I am happy to test this out and even contribute with code and documentation. thanks.

@rememberlenny
Copy link

You are a boss.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment