FEATURE: use groups to control who sees ads
A new setting has been added in Admin > Settings > Ad Plugin called "no ads for groups". Add group names to this list. If a user belongs to any of the groups, they will not see any ads. This is an alternative to using trust level settings like "adsense through trust level".
This commit is contained in:
parent
6097e6f097
commit
4fd7caffd6
|
@ -0,0 +1,23 @@
|
||||||
|
import computed from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
@computed()
|
||||||
|
showToGroups: function() {
|
||||||
|
const currentUser = Discourse.User.current();
|
||||||
|
|
||||||
|
if (
|
||||||
|
!currentUser ||
|
||||||
|
!currentUser.get("groups") ||
|
||||||
|
!this.siteSettings.no_ads_for_groups ||
|
||||||
|
this.siteSettings.no_ads_for_groups.length === 0
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const noAdsGroupNames = this.siteSettings.no_ads_for_groups.split("|");
|
||||||
|
|
||||||
|
return !currentUser
|
||||||
|
.get("groups")
|
||||||
|
.any(group => noAdsGroupNames.includes(group.name));
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,3 +1,4 @@
|
||||||
|
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad_component";
|
||||||
import {
|
import {
|
||||||
default as computed,
|
default as computed,
|
||||||
observes
|
observes
|
||||||
|
@ -146,7 +147,7 @@ if (Discourse.SiteSettings.adsense_publisher_code) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default AdComponent.extend({
|
||||||
classNameBindings: [
|
classNameBindings: [
|
||||||
":google-adsense",
|
":google-adsense",
|
||||||
"classForSlot",
|
"classForSlot",
|
||||||
|
@ -193,7 +194,7 @@ export default Ember.Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
@observes("listLoading")
|
@observes("listLoading")
|
||||||
waitForLoad: function() {
|
waitForLoad() {
|
||||||
if (this.get("adRequested")) {
|
if (this.get("adRequested")) {
|
||||||
return;
|
return;
|
||||||
} // already requested that this ad unit be populated
|
} // already requested that this ad unit be populated
|
||||||
|
@ -203,34 +204,34 @@ export default Ember.Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed("ad_width")
|
@computed("ad_width")
|
||||||
isResponsive: function(adWidth) {
|
isResponsive(adWidth) {
|
||||||
return adWidth === "auto";
|
return adWidth === "auto";
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed("placement", "checkTrustLevels")
|
@computed("placement", "showAd")
|
||||||
classForSlot: function(placement, shown) {
|
classForSlot(placement, showAd) {
|
||||||
return shown ? `adsense-${placement}`.htmlSafe() : "";
|
return showAd ? `adsense-${placement}`.htmlSafe() : "";
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed("isResponsive")
|
@computed("isResponsive")
|
||||||
autoAdFormat: function(isResponsive) {
|
autoAdFormat(isResponsive) {
|
||||||
return isResponsive ? "auto".htmlSafe() : false;
|
return isResponsive ? "auto".htmlSafe() : false;
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed("ad_width", "ad_height", "isResponsive")
|
@computed("ad_width", "ad_height", "isResponsive")
|
||||||
adWrapperStyle: function(w, h, isResponsive) {
|
adWrapperStyle(w, h, isResponsive) {
|
||||||
return (isResponsive ? "" : `width: ${w}; height: ${h};`).htmlSafe();
|
return (isResponsive ? "" : `width: ${w}; height: ${h};`).htmlSafe();
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed("adWrapperStyle", "isResponsive")
|
@computed("adWrapperStyle", "isResponsive")
|
||||||
adInsStyle: function(adWrapperStyle, isResponsive) {
|
adInsStyle(adWrapperStyle, isResponsive) {
|
||||||
return `display: ${
|
return `display: ${
|
||||||
isResponsive ? "block" : "inline-block"
|
isResponsive ? "block" : "inline-block"
|
||||||
}; ${adWrapperStyle}`.htmlSafe();
|
}; ${adWrapperStyle}`.htmlSafe();
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed()
|
@computed()
|
||||||
checkTrustLevels: function() {
|
showToTrustLevel() {
|
||||||
return !(
|
return !(
|
||||||
currentUser &&
|
currentUser &&
|
||||||
currentUser.get("trust_level") >
|
currentUser.get("trust_level") >
|
||||||
|
@ -238,8 +239,12 @@ export default Ember.Component.extend({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed("checkTrustLevels")
|
@computed("showToTrustLevel", "showToGroups")
|
||||||
showAd: function(shown) {
|
showAd(showToTrustLevel, showToGroups) {
|
||||||
return shown && Discourse.SiteSettings.adsense_publisher_code;
|
return (
|
||||||
|
showToTrustLevel &&
|
||||||
|
showToGroups &&
|
||||||
|
Discourse.SiteSettings.adsense_publisher_code
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad_component";
|
||||||
|
import {
|
||||||
|
default as computed,
|
||||||
|
observes,
|
||||||
|
on
|
||||||
|
} from "ember-addons/ember-computed-decorators";
|
||||||
import loadScript from "discourse/lib/load-script";
|
import loadScript from "discourse/lib/load-script";
|
||||||
|
|
||||||
var currentUser = Discourse.User.current(),
|
var currentUser = Discourse.User.current(),
|
||||||
|
@ -198,51 +204,56 @@ function loadGoogle() {
|
||||||
return _promise;
|
return _promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default AdComponent.extend({
|
||||||
classNameBindings: ["adUnitClass"],
|
classNameBindings: ["adUnitClass"],
|
||||||
classNames: ["google-dfp-ad"],
|
classNames: ["google-dfp-ad"],
|
||||||
loadedGoogletag: false,
|
loadedGoogletag: false,
|
||||||
refreshOnChange: null,
|
refreshOnChange: null,
|
||||||
|
|
||||||
divId: function() {
|
@computed("placement", "postNumber")
|
||||||
if (this.get("postNumber")) {
|
divId(placement, postNumber) {
|
||||||
return (
|
if (postNumber) {
|
||||||
"div-gpt-ad-" + this.get("placement") + "-" + this.get("postNumber")
|
return `div-gpt-ad-${placement}-${postNumber}`;
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return "div-gpt-ad-" + this.get("placement");
|
return `div-gpt-ad-${placement}`;
|
||||||
}
|
}
|
||||||
}.property("placement", "postNumber"),
|
},
|
||||||
|
|
||||||
adUnitClass: function() {
|
@computed("placement", "showAd")
|
||||||
return "dfp-ad-" + this.get("placement");
|
adUnitClass(placement, showAd) {
|
||||||
}.property("placement"),
|
return showAd ? `dfp-ad-${placement}` : "";
|
||||||
|
},
|
||||||
|
|
||||||
adWrapperStyle: function() {
|
@computed("width", "height")
|
||||||
return `width: ${this.get("width")}px; height: ${this.get(
|
adWrapperStyle(w, h) {
|
||||||
"height"
|
return `width: ${w}px; height: ${h}px;`.htmlSafe();
|
||||||
)}px;`.htmlSafe();
|
},
|
||||||
}.property("width", "height"),
|
|
||||||
|
|
||||||
adTitleStyleMobile: function() {
|
@computed("width")
|
||||||
return `width: ${this.get("width")}px;`.htmlSafe();
|
adTitleStyleMobile(w) {
|
||||||
}.property("width"),
|
return `width: ${w}px;`.htmlSafe();
|
||||||
|
},
|
||||||
|
|
||||||
showAd: function() {
|
@computed("showToTrustLevel", "showToGroups")
|
||||||
|
showAd(showToTrustLevel, showToGroups) {
|
||||||
return (
|
return (
|
||||||
Discourse.SiteSettings.dfp_publisher_id && this.get("checkTrustLevels")
|
Discourse.SiteSettings.dfp_publisher_id &&
|
||||||
|
showToTrustLevel &&
|
||||||
|
showToGroups
|
||||||
);
|
);
|
||||||
}.property("checkTrustLevels"),
|
},
|
||||||
|
|
||||||
checkTrustLevels: function() {
|
@computed()
|
||||||
|
showToTrustLevel() {
|
||||||
return !(
|
return !(
|
||||||
currentUser &&
|
currentUser &&
|
||||||
currentUser.get("trust_level") >
|
currentUser.get("trust_level") >
|
||||||
Discourse.SiteSettings.dfp_through_trust_level
|
Discourse.SiteSettings.dfp_through_trust_level
|
||||||
);
|
);
|
||||||
}.property("trust_level"),
|
},
|
||||||
|
|
||||||
refreshAd: function() {
|
@observes("refreshOnChange")
|
||||||
|
refreshAd() {
|
||||||
var slot = ads[this.get("divId")];
|
var slot = ads[this.get("divId")];
|
||||||
if (!(slot && slot.ad)) {
|
if (!(slot && slot.ad)) {
|
||||||
return;
|
return;
|
||||||
|
@ -260,9 +271,10 @@ export default Ember.Component.extend({
|
||||||
window.googletag.pubads().refresh([ad]);
|
window.googletag.pubads().refresh([ad]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}.observes("refreshOnChange"),
|
},
|
||||||
|
|
||||||
_initGoogleDFP: function() {
|
@on("didInsertElement")
|
||||||
|
_initGoogleDFP() {
|
||||||
if (!this.get("showAd")) {
|
if (!this.get("showAd")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -287,7 +299,7 @@ export default Ember.Component.extend({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}.on("didInsertElement"),
|
},
|
||||||
|
|
||||||
willRender() {
|
willRender() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
@ -300,7 +312,8 @@ export default Ember.Component.extend({
|
||||||
this.set("height", size.height);
|
this.set("height", size.height);
|
||||||
},
|
},
|
||||||
|
|
||||||
cleanup: function() {
|
@on("willDestroyElement")
|
||||||
|
cleanup() {
|
||||||
destroySlot(this.get("divId"));
|
destroySlot(this.get("divId"));
|
||||||
}.on("willDestroyElement")
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,6 +6,7 @@ en:
|
||||||
admin:
|
admin:
|
||||||
site_settings:
|
site_settings:
|
||||||
categories:
|
categories:
|
||||||
|
ad_plugin: 'Ad Plugin'
|
||||||
dfp_plugin: 'DFP/Ad Manager'
|
dfp_plugin: 'DFP/Ad Manager'
|
||||||
adsense_plugin: 'AdSense'
|
adsense_plugin: 'AdSense'
|
||||||
amazon_plugin: 'Amazon'
|
amazon_plugin: 'Amazon'
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
en:
|
en:
|
||||||
site_settings:
|
site_settings:
|
||||||
|
no_ads_for_groups: "Don't show ads to users in these groups."
|
||||||
|
|
||||||
dfp_publisher_id: "Input your Google Ad Manager (formerly called DFP) network code, which is found in your network settings."
|
dfp_publisher_id: "Input your Google Ad Manager (formerly called DFP) network code, which is found in your network settings."
|
||||||
dfp_through_trust_level: "Show your ads to users based on trust levels. Users with trust level higher than this value will not see ads."
|
dfp_through_trust_level: "Show your ads to users based on trust levels. Users with trust level higher than this value will not see ads."
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
ad_plugin:
|
||||||
|
no_ads_for_groups:
|
||||||
|
client: true
|
||||||
|
default: ""
|
||||||
|
type: list
|
||||||
|
choices: "Group.pluck(:name)"
|
||||||
|
list_type: compact
|
||||||
|
|
||||||
adsense_plugin:
|
adsense_plugin:
|
||||||
adsense_publisher_code:
|
adsense_publisher_code:
|
||||||
client: true
|
client: true
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { acceptance, replaceCurrentUser } from "helpers/qunit-helpers";
|
import { acceptance, replaceCurrentUser } from "helpers/qunit-helpers";
|
||||||
|
import groupFixtures from "fixtures/group-fixtures";
|
||||||
|
|
||||||
acceptance("AdSense", {
|
acceptance("AdSense", {
|
||||||
loggedIn: true,
|
loggedIn: true,
|
||||||
settings: {
|
settings: {
|
||||||
|
no_ads_for_groups: "discourse",
|
||||||
adsense_publisher_code: "MYADSENSEID",
|
adsense_publisher_code: "MYADSENSEID",
|
||||||
adsense_through_trust_level: 2,
|
adsense_through_trust_level: 2,
|
||||||
adsense_topic_list_top_code: "list_top_ad_unit",
|
adsense_topic_list_top_code: "list_top_ad_unit",
|
||||||
|
@ -54,3 +56,17 @@ test("no ads for trust level 3", async assert => {
|
||||||
"it should render 0 ads"
|
"it should render 0 ads"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.only("can omit ads based on groups", async assert => {
|
||||||
|
replaceCurrentUser({
|
||||||
|
staff: false,
|
||||||
|
trust_level: 1,
|
||||||
|
groups: [groupFixtures["/groups/discourse.json"].group]
|
||||||
|
});
|
||||||
|
await visit("/t/280");
|
||||||
|
assert.equal(
|
||||||
|
find(".google-adsense.adsense-post-bottom").length,
|
||||||
|
0,
|
||||||
|
"it should render 0 ads"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
import { acceptance, replaceCurrentUser } from "helpers/qunit-helpers";
|
||||||
|
import groupFixtures from "fixtures/group-fixtures";
|
||||||
|
|
||||||
|
acceptance("DFP Ads", {
|
||||||
|
loggedIn: true,
|
||||||
|
settings: {
|
||||||
|
no_ads_for_groups: "discourse",
|
||||||
|
dfp_publisher_id: "MYdfpID",
|
||||||
|
dfp_through_trust_level: 2,
|
||||||
|
dfp_topic_list_top_code: "list_top_ad_unit",
|
||||||
|
dfp_topic_list_top_ad_sizes: "728*90 - leaderboard",
|
||||||
|
dfp_mobile_topic_list_top_code: "mobile_list_top_ad_unit",
|
||||||
|
dfp_mobile_topic_list_top_ad_size: "300*250 - medium rectangle",
|
||||||
|
dfp_post_bottom_code: "post_bottom_ad_unit",
|
||||||
|
dfp_post_bottom_ad_sizes: "728*90 - leaderboard",
|
||||||
|
dfp_mobile_post_bottom_code: "mobile_post_bottom_ad_unit",
|
||||||
|
dfp_mobile_post_bottom_ad_size: "300*250 - medium rectangle",
|
||||||
|
dfp_nth_post_code: 6
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("correct number of ads should show", async assert => {
|
||||||
|
replaceCurrentUser({ staff: false, trust_level: 1 });
|
||||||
|
await visit("/t/280"); // 20 posts
|
||||||
|
const ads = find(".google-dfp-ad.dfp-ad-post-bottom");
|
||||||
|
assert.equal(ads.length, 3, "it should render 3 ads");
|
||||||
|
assert.equal(
|
||||||
|
find("#post_6 + .widget-connector").find(
|
||||||
|
".google-dfp-ad.dfp-ad-post-bottom"
|
||||||
|
).length,
|
||||||
|
1,
|
||||||
|
"ad after 6th post"
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
find("#post_12 + .widget-connector").find(
|
||||||
|
".google-dfp-ad.dfp-ad-post-bottom"
|
||||||
|
).length,
|
||||||
|
1,
|
||||||
|
"ad after 12th post"
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
find("#post_18 + .widget-connector").find(
|
||||||
|
".google-dfp-ad.dfp-ad-post-bottom"
|
||||||
|
).length,
|
||||||
|
1,
|
||||||
|
"ad after 18th post"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("no ads for trust level 3", async assert => {
|
||||||
|
replaceCurrentUser({ staff: false, trust_level: 3 });
|
||||||
|
await visit("/t/280");
|
||||||
|
assert.equal(
|
||||||
|
find(".google-dfp-ad.dfp-ad-post-bottom").length,
|
||||||
|
0,
|
||||||
|
"it should render 0 ads"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("can omit ads based on groups", async assert => {
|
||||||
|
replaceCurrentUser({
|
||||||
|
staff: false,
|
||||||
|
trust_level: 1,
|
||||||
|
groups: [groupFixtures["/groups/discourse.json"].group]
|
||||||
|
});
|
||||||
|
await visit("/t/280");
|
||||||
|
assert.equal(
|
||||||
|
find(".google-dfp-ad.dfp-ad-post-bottom").length,
|
||||||
|
0,
|
||||||
|
"it should render 0 ads"
|
||||||
|
);
|
||||||
|
});
|
Loading…
Reference in New Issue