FEATURE: house ads can be configured to alternate with other ads
Use the new "house ads frequency" site setting to configure how often house ads should show, as a percentage. This only applies in ad placements where other ad networks are configured to appear.
This commit is contained in:
parent
cdc14398ba
commit
4bd2035866
|
@ -24,7 +24,10 @@ module ::AdPlugin
|
|||
ad_names = settings.values.map { |v| v.split('|') }.flatten.uniq
|
||||
ads = AdPlugin::HouseAd.all.select { |ad| ad_names.include?(ad.name) }
|
||||
{
|
||||
settings: settings.merge(after_nth_post: SiteSetting.house_ads_after_nth_post),
|
||||
settings: settings.merge(
|
||||
after_nth_post: SiteSetting.house_ads_after_nth_post,
|
||||
house_ads_frequency: SiteSetting.house_ads_frequency
|
||||
),
|
||||
creatives: ads.inject({}) { |h, ad| h[ad.name] = ad.html; h }
|
||||
}
|
||||
end
|
||||
|
|
|
@ -1,14 +1,24 @@
|
|||
import computed from "ember-addons/ember-computed-decorators";
|
||||
import AdComponent from "discourse/plugins/discourse-adplugin/discourse/components/ad-component";
|
||||
import {
|
||||
default as computed,
|
||||
observes
|
||||
} from "ember-addons/ember-computed-decorators";
|
||||
|
||||
const adConfig = Ember.Object.create({
|
||||
"google-adsense": {
|
||||
settingPrefix: "adsense" // settings follow naming convention
|
||||
settingPrefix: "adsense", // settings follow naming convention
|
||||
enabledSetting: "adsense_publisher_code",
|
||||
nthPost: "adsense_nth_post_code"
|
||||
},
|
||||
"google-dfp-ad": {
|
||||
settingPrefix: "dfp" // settings follow naming convention
|
||||
settingPrefix: "dfp", // settings follow naming convention
|
||||
enabledSetting: "dfp_publisher_id",
|
||||
nthPost: "dfp_nth_post_code"
|
||||
},
|
||||
"amazon-product-links": {
|
||||
settingPrefix: "amazon",
|
||||
enabledSetting: false,
|
||||
nthPost: "amazon_nth_post_code",
|
||||
desktop: {
|
||||
"topic-list-top": "amazon_topic_list_top_src_code",
|
||||
"post-bottom": "amazon_post_bottom_src_code",
|
||||
|
@ -25,6 +35,8 @@ const adConfig = Ember.Object.create({
|
|||
},
|
||||
"codefund-ad": {
|
||||
settingPrefix: "codefund",
|
||||
enabledSetting: "codefund_property_id",
|
||||
nthPost: "codefund_nth_post",
|
||||
desktop: {
|
||||
"topic-list-top": "codefund_top_of_topic_list_enabled",
|
||||
"post-bottom": "codefund_below_post_enabled",
|
||||
|
@ -34,6 +46,7 @@ const adConfig = Ember.Object.create({
|
|||
},
|
||||
"carbonads-ad": {
|
||||
settingPrefix: "carbonads",
|
||||
enabledSetting: "carbonads_serve_id",
|
||||
desktop: {
|
||||
"topic-list-top": "carbonads_topic_list_top_enabled",
|
||||
"post-bottom": false,
|
||||
|
@ -43,47 +56,133 @@ const adConfig = Ember.Object.create({
|
|||
}
|
||||
});
|
||||
|
||||
export default Ember.Component.extend({
|
||||
@computed("placement")
|
||||
adComponents(placement) {
|
||||
// Check house ads first
|
||||
const houseAds = this.site.get("house_creatives");
|
||||
if (!houseAds || !houseAds.settings) {
|
||||
return [];
|
||||
const displayCounts = {
|
||||
houseAds: 0,
|
||||
allAds: 0
|
||||
};
|
||||
|
||||
export default AdComponent.extend({
|
||||
needsUpdate: false,
|
||||
|
||||
/**
|
||||
* For a given ad placement and optionally a post number if in between posts,
|
||||
* list all ad network names that are configured to show there.
|
||||
*/
|
||||
@computed("placement", "postNumber")
|
||||
availableAdTypes(placement, postNumber) {
|
||||
let types = [];
|
||||
const houseAds = this.site.get("house_creatives"),
|
||||
placeUnderscored = placement.replace(/-/g, "_");
|
||||
|
||||
if (houseAds && houseAds.settings) {
|
||||
const adsForSlot = houseAds.settings[placeUnderscored];
|
||||
|
||||
if (
|
||||
Object.keys(houseAds.creatives).length > 0 &&
|
||||
!Ember.isBlank(adsForSlot) &&
|
||||
(!postNumber ||
|
||||
this.isNthPost(parseInt(houseAds.settings.after_nth_post, 10)))
|
||||
) {
|
||||
types.push("house-ad");
|
||||
}
|
||||
}
|
||||
|
||||
const adsForSlot = houseAds.settings[placement.replace(/-/g, "_")];
|
||||
|
||||
if (
|
||||
Object.keys(houseAds.creatives).length > 0 &&
|
||||
!Ember.isBlank(adsForSlot)
|
||||
) {
|
||||
return ["house-ad"];
|
||||
}
|
||||
|
||||
return Object.keys(adConfig).filter(adNetwork => {
|
||||
Object.keys(adConfig).forEach(adNetwork => {
|
||||
const config = adConfig[adNetwork];
|
||||
let settingNames = null,
|
||||
name;
|
||||
|
||||
if (this.site.mobileView) {
|
||||
settingNames = config.mobile || config.desktop;
|
||||
} else {
|
||||
settingNames = config.desktop;
|
||||
}
|
||||
if (
|
||||
config.enabledSetting &&
|
||||
!Ember.isBlank(this.siteSettings[config.enabledSetting]) &&
|
||||
(!postNumber ||
|
||||
!config.nthPost ||
|
||||
this.isNthPost(parseInt(this.siteSettings[config.nthPost], 10)))
|
||||
) {
|
||||
if (this.site.mobileView) {
|
||||
settingNames = config.mobile || config.desktop;
|
||||
} else {
|
||||
settingNames = config.desktop;
|
||||
}
|
||||
|
||||
if (settingNames) {
|
||||
name = settingNames[placement];
|
||||
}
|
||||
if (settingNames) {
|
||||
name = settingNames[placement];
|
||||
}
|
||||
|
||||
if (name === undefined) {
|
||||
// follows naming convention: prefix_(mobile_)_{placement}_code
|
||||
name = `${config.settingPrefix}_${
|
||||
this.site.mobileView ? "mobile_" : ""
|
||||
}${placement.replace(/-/g, "_")}_code`;
|
||||
}
|
||||
if (name === undefined) {
|
||||
// follows naming convention: prefix_(mobile_)_{placement}_code
|
||||
name = `${config.settingPrefix}_${
|
||||
this.site.mobileView ? "mobile_" : ""
|
||||
}${placeUnderscored}_code`;
|
||||
}
|
||||
|
||||
return name !== false && !Ember.isBlank(this.siteSettings[name]);
|
||||
if (name !== false && !Ember.isBlank(this.siteSettings[name])) {
|
||||
types.push(adNetwork);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return types;
|
||||
},
|
||||
|
||||
/**
|
||||
* When house ads are configured to alternate with other ad networks, we
|
||||
* need to trigger an update of which ad component is shown after
|
||||
* navigating between topic lists or topics.
|
||||
*/
|
||||
@observes("refreshOnChange")
|
||||
changed() {
|
||||
if (this.get("listLoading")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// force adComponents to be recomputed
|
||||
this.notifyPropertyChange("needsUpdate");
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a list of the names of ad components that should be rendered
|
||||
* in the given ad placement. It handles alternating between house ads
|
||||
* and other ad networks.
|
||||
*/
|
||||
@computed("placement", "availableAdTypes", "needsUpdate")
|
||||
adComponents(placement, availableAdTypes) {
|
||||
if (
|
||||
!availableAdTypes.includes("house-ad") ||
|
||||
availableAdTypes.length === 1
|
||||
) {
|
||||
// Current behaviour is to allow multiple ads from different networks
|
||||
// to show in the same place. We could change this to choose one somehow.
|
||||
return availableAdTypes;
|
||||
}
|
||||
|
||||
const houseAds = this.site.get("house_creatives");
|
||||
let houseAdsSkipped = false;
|
||||
|
||||
if (houseAds.settings.house_ads_frequency === 100) {
|
||||
// house always wins
|
||||
return ["house-ad"];
|
||||
} else if (houseAds.settings.house_ads_frequency > 0) {
|
||||
// show house ads the given percent of the time
|
||||
if (
|
||||
displayCounts.allAds === 0 ||
|
||||
(100 * displayCounts.houseAds) / displayCounts.allAds <
|
||||
houseAds.settings.house_ads_frequency
|
||||
) {
|
||||
displayCounts.houseAds += 1;
|
||||
displayCounts.allAds += 1;
|
||||
return ["house-ad"];
|
||||
} else {
|
||||
houseAdsSkipped = true;
|
||||
}
|
||||
}
|
||||
|
||||
const networkNames = availableAdTypes.filter(x => x !== "house-ad");
|
||||
|
||||
if (houseAdsSkipped) {
|
||||
displayCounts.allAds += networkNames.length;
|
||||
}
|
||||
|
||||
return networkNames;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{{#each adComponents as |adComponent|}}
|
||||
{{component adComponent
|
||||
placement=placement
|
||||
refreshOnChange=refreshOnChange
|
||||
category=category
|
||||
listLoading=listLoading
|
||||
postNumber=postNumber}}
|
||||
placement=placement
|
||||
refreshOnChange=refreshOnChange
|
||||
category=category
|
||||
listLoading=listLoading
|
||||
postNumber=postNumber}}
|
||||
{{/each}}
|
||||
|
|
|
@ -2,6 +2,7 @@ en:
|
|||
site_settings:
|
||||
no_ads_for_groups: "Don't show ads to users in these groups."
|
||||
house_ads_after_nth_post: 'If "Between posts" house ads are defined, show an ad after every N posts, where N is this value.'
|
||||
house_ads_frequency: "If other ad networks are configured to show in an ad slot, how often should house ads be shown, as a percentage."
|
||||
|
||||
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."
|
||||
|
|
|
@ -8,6 +8,11 @@ ad_plugin:
|
|||
default: 20
|
||||
min: 1
|
||||
max: 10000
|
||||
house_ads_frequency:
|
||||
client: true
|
||||
default: 100
|
||||
min: 0
|
||||
max: 100
|
||||
|
||||
adsense_plugin:
|
||||
adsense_publisher_code:
|
||||
|
|
Loading…
Reference in New Issue