AdButler support (#80)

AdButler support (#80)

diff --git a/README.md b/README.md
index c41f36e..3f10199 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,7 @@ This is the official Discourse advertising plugin.  It allows advertisements to
 * [Amazon Affiliates](http://affiliate-program.amazon.com) - Banner and Product Link Ads
 * [CodeFund](https://codefund.io) - Ethical Ad Platform for Developers
 * [Carbon Ads](https://www.carbonads.net/)
+* [AdButler](https://www.adbutler.com/)
 
 
 ## Quick Start in 3 Steps
@@ -81,6 +82,7 @@ the ad slots. The ads will start showing as soon as you add them to slots.
 <li>DFP - if using the DoubleClick for Publishers advertisement platform.</li>
 <li>CodeFund - if using the CodeFund ethical advertisement platform.</li>
 <li>Carbon Ads - if using the Carbon Ads advertisement platform.</li>
+<li>AdButler - if using the AdButler advertisement platform.</li>
 </ul>
 </ul>
 
@@ -113,6 +115,13 @@ Only for Product Link and Banner Ads.
 
 ![Carbon Ads](https://d11a6trkgmumsb.cloudfront.net/original/3X/3/a/3acc7488db2b53733cdd427d3cb1b76361c786e1.png)
 
+##### AdButler Ads Zone URL to Discourse's Site Settings
+
+If you browse to a zone in the AdButler admin, then you can find the Publisher ID (PPPPPP) and the Zone ID (ZZZZZZ) in the URL:
+
+`https://admin.adbutler.com/?ID=PPPPPP&p=textadzone.view&zoneID=ZZZZZZ`
+
+
 ### Step 3 - See Your Ad
 
 Once you've configured your settings and your advertising platform has ads that are ready to serve, navigate to the page where you've inputted for the location and you should see ads.
diff --git a/assets/javascripts/discourse/components/ad-slot.js.es6 b/assets/javascripts/discourse/components/ad-slot.js.es6
index 02d3261..b34f202 100644
--- a/assets/javascripts/discourse/components/ad-slot.js.es6
+++ b/assets/javascripts/discourse/components/ad-slot.js.es6
@@ -53,6 +53,23 @@ const adConfig = Ember.Object.create({
       "topic-above-post-stream": "carbonads_above_post_stream_enabled",
       "topic-above-suggested": false
     }
+  },
+  "adbutler-ad": {
+    settingPrefix: "adbutler",
+    enabledSetting: "adbutler_publisher_id",
+    desktop: {
+      "topic-list-top": "adbutler_topic_list_top_zone_id",
+      "post-bottom": "adbutler_post_bottom_zone_id",
+      "topic-above-post-stream": "adbutler_topic_above_post_stream_zone_id",
+      "topic-above-suggested": "adbutler_topic_above_suggested_zone_id"
+    },
+    mobile: {
+      "topic-list-top": "adbutler_mobile_topic_list_top_zone_id",
+      "post-bottom": "adbutler_mobile_post_bottom_zone_id",
+      "topic-above-post-stream":
+        "adbutler_mobile_topic_above_post_stream_zone_id",
+      "topic-above-suggested": "adbutler_mobile_topic_above_suggested_zone_id"
+    }
   }
 });
 
diff --git a/assets/javascripts/discourse/components/adbutler-ad.js.es6 b/assets/javascripts/discourse/components/adbutler-ad.js.es6
new file mode 100644
index 0000000..b2fe1f2
--- /dev/null
+++ b/assets/javascripts/discourse/components/adbutler-ad.js.es6
@@ -0,0 +1,131 @@
+import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
+import { default as computed, observes } from "ember-addons/ember-computed-decorators";
+import loadScript from "discourse/lib/load-script";
+
+const publisherId = Discourse.SiteSettings.adbutler_publisher_id;
+const adserverHostname = Discourse.SiteSettings.adbutler_adserver_hostname;
+
+let _loaded = false,
+    _promise = null,
+    _c = 0;
+
+function loadAdbutler() {
+  if (_loaded) {
+    return Ember.RSVP.resolve();
+  }
+
+  if (_promise) {
+    return _promise;
+  }
+
+  _promise = loadScript('https://' + adserverHostname + '/app.js', { scriptTag: true }).then(function() {
+    _loaded = true;
+  });
+
+  return _promise;
+}
+
+export default AdComponent.extend({
+
+  divs: null,
+
+  init() {
+    let dimensions = [728,90];
+    let configKey = 'adbutler_';
+    let className = 'adbutler-';
+    let dimClassName = 'adbutler-ad';
+
+    this.set('divs', []);
+
+    if (this.site.mobileView) {
+      dimensions = [320,50];
+      configKey += 'mobile_';
+      className += 'mobile-';
+      dimClassName = 'adbutler-mobile-ad';
+    }
+
+    configKey += this.get("placement").replace(/-/g, '_') + '_zone_id';
+    this.set("configKey", configKey);
+
+    className += this.get("placement");
+    this.set("className", className + ' ' + dimClassName);
+
+    let zoneId = this.siteSettings[configKey];
+    this.set("zoneId", zoneId);
+
+    let divId = 'placement-' + zoneId + '-' + _c;
+    this.set("divId", divId);
+    _c++;
+    this.divs.push({
+      divId: divId,
+      publisherId: publisherId,
+      zoneId: zoneId,
+      dimensions: dimensions
+    });
+
+    this.set("publisherId", publisherId);
+    this._super();
+  },
+
+  _triggerAds() {
+    loadAdbutler().then(function() {
+      if(this.divs.length > 0) {
+        let abkw = window.abkw || '';
+        AdButler.ads.push({
+          handler: function(opt){ 
+            AdButler.register(opt.place.publisherId, opt.place.zoneId, opt.place.dimensions, opt.place.divId, opt);
+          }, 
+          opt: { place: this.divs.pop(), keywords: abkw, domain: adserverHostname, click:'CLICK_MACRO_PLACEHOLDER' }
+        });
+      }
+    }.bind(this));
+  },
+
+  didInsertElement() {
+    this._super();
+    Ember.run.scheduleOnce("afterRender", this, this._triggerAds);
+  },
+
+  @observes("listLoading")
+  waitForLoad() {
+    if (this.get("adRequested")) {
+      return;
+    } // already requested that this ad unit be populated
+    if (!this.get("listLoading")) {
+      Ember.run.scheduleOnce("afterRender", this, this._triggerAds);
+    }
+  },
+
+  @computed("currentUser.trust_level")
+  showToTrustLevel(trustLevel) {
+    return !(
+      trustLevel &&
+      trustLevel > Discourse.SiteSettings.adbutler_through_trust_level
+    );
+  },
+
+  @computed(
+    "showToTrustLevel", 
+    "showToGroups", 
+    "showAfterPost",
+    "showOnCurrentPage",
+  )
+  showAd(showToTrustLevel, showToGroups, showAfterPost, showOnCurrentPage) {
+    return (
+      publisherId &&
+      showToTrustLevel &&
+      showToGroups &&
+      showAfterPost &&
+      showOnCurrentPage
+    );
+  },
+
+  @computed("postNumber")
+  showAfterPost(postNumber) {
+    if (!postNumber) {
+      return true;
+    }
+    return this.isNthPost(parseInt(this.siteSettings.adbutler_nth_post));
+  }
+
+});
diff --git a/assets/javascripts/discourse/templates/components/adbutler-ad.hbs b/assets/javascripts/discourse/templates/components/adbutler-ad.hbs
new file mode 100644
index 0000000..ef2db38
--- /dev/null
+++ b/assets/javascripts/discourse/templates/components/adbutler-ad.hbs
@@ -0,0 +1,3 @@
+{{#if showAd}}
+<div id={{divId}} class={{className}}></div>
+{{/if}}
diff --git a/assets/stylesheets/adplugin.scss b/assets/stylesheets/adplugin.scss
index f1067cc..3581fac 100644
--- a/assets/stylesheets/adplugin.scss
+++ b/assets/stylesheets/adplugin.scss
@@ -238,6 +238,30 @@
   color: $quaternary !important;
 }
 
+.adbutler-ad {
+  width: 728px;
+  height: 90px;
+}
+
+.adbutler-mobile-ad {
+  width: 320px;
+  height: 50px;
+}
+
+.adbutler-topic-list-top, .adbutler-topic-above-suggested {
+  margin: 10px;
+  text-align: center;
+}
+
+.adbutler-topic-above-post-stream {
+  margin: 10px 0px 10px 0px;
+}
+
+.adbutler-post-bottom {
+  margin: 10px 0px 10px 56px;
+} 
+
+
 .adplugin-mgmt {
   .house-ads-actions {
     .btn {
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 4448240..4fe27f5 100755
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -12,6 +12,7 @@ en:
           amazon_plugin: 'Amazon'
           codefund_plugin: 'CodeFund'
           carbonads_plugin: 'Carbon Ads'
+          adbutler_plugin: 'AdButler'
       adplugin:
         house_ads:
           title: "House Ads"
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index cc887bb..28ee76d 100755
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml

[... diff too long, it was truncated ...]

GitHub sha: 19f0457e

1 Like