Creating an Anti AdBlock Plugin for WordPress
Editor’s note: Ad-blocking (and online advertising in general) is a controversial subject. Some dislike ads altogether, and block them on principle, others say this robs publishers of income. This tutorial is one developer’s attempt at a compromise. What do you think? Let us know in the comments below.
In this tutorial, we will create a WordPress plugin that can disable the website for users using AdBlock or display alternative ads to AdBlock users from the same domain as the website.
This plugin can be useful if your website is completely dependent on ads for generating revenue and where users consume a high amount of resources. For example, a video sharing site may want to ban a site from playing videos or display alternative ads for AdBlock installed users. One such example is TED.com, as shown above. You can see TED.com requests you to unblock ads for their site.
How Does AdBlock Work?
AdBlock maintains a list of various advertising network domain names and a list of advertising specific keywords.
AdBlock works by blocking image, iframe, script and Flash HTTP requests that match known advertiser domain or advertiser specific keywords that are on their list. After the requests are blocked, it also changes the CSS properties of the blocked HTML elements to hide them.
AdBlock allows you to expand on what can be blocked by adding filters.
Alexis Ulrich has written about ad blocking technology if you’re interested in reading more on the topic.
Setting up Plugin Directory and Files
Here’s the directory structure of the plugin we’re going to be creating:
--alternative -alternative.php -custom.css -index.js
alternative
is the plugin directory. If you want to change the name, that’s fine. Just make sure you don’t call it anything that the keywords specific blocking would trigger, otherwise enqueuing of index.js
will fail.
Creating a Admin Panel Menu Item
First, we need to add a Anti AdBlock settings page to WordPress admin panel. Before we create a settings page, we need to create a sub menu item for the ‘settings’ parent menu item.
Here’s the code we’ll use to create a sub menu item. Place it in the alternative.php
file.
function add_anti_adblock_menu_item()
{
add_submenu_page("options-general.php", "Anti Adblock", "Anti Adblock", "manage_options", "anti-adblock", "anti_adblock_page");
}
function anti_adblock_page()
{
}
add_action("admin_menu", "add_anti_adblock_menu_item");
This code creates a menu item and attaches a settings page to it.
Creating a Settings Page
Next, we need to use the WordPress Settings API to populate the Anti Adblock Settings page with desired options.
Here’s the code for displaying various options on the settings page using the WordPress Settings API. Place this in the alternative.php
file.
function anti_adblock_page()
{
?>
<div class="wrap">
<h1>Anti Adblock</h1>
<form method="post" action="options.php">
<?php
settings_fields("anti_adblock_config_section");
do_settings_sections("anti-adblock");
submit_button();
?>
</form>
</div>
<?php
}
function anti_adblock_settings()
{
add_settings_section("anti_adblock_config_section", "", null, "anti-adblock");
add_settings_field("disable_website", "Do you want to disable website?", "disable_website_checkbox", "anti-adblock", "anti_adblock_config_section");
add_settings_field("disable_website_url", "Image to display when website is disabled", "disable_website_image_input_field", "anti-adblock", "anti_adblock_config_section");
add_settings_field("alternative_ads_code", "Do you want to display alternative ads code", "alternative_ads_checkbox", "anti-adblock", "anti_adblock_config_section");
add_settings_field("alternative_ads_selector_1", "Alternaive Ad Code 1 Selector", "alternative_ads_selector_1_input_field", "anti-adblock", "anti_adblock_config_section");
add_settings_field("alternative_ads_code_1", "Alternaive Ad Code 1", "alternative_ads_code_1_input_field", "anti-adblock", "anti_adblock_config_section");
add_settings_field("alternative_ads_selector_2", "Alternaive Ad Code 2 Selector", "alternative_ads_selector_2_input_field", "anti-adblock", "anti_adblock_config_section");
add_settings_field("alternative_ads_code_2", "Alternaive Ad Code 2", "alternative_ads_code_2_input_field", "anti-adblock", "anti_adblock_config_section");
add_settings_field("custom_css", "Custom CSS", "custom_css_input_field", "anti-adblock", "anti_adblock_config_section");
register_setting("anti_adblock_config_section", "disable_website");
register_setting("anti_adblock_config_section", "disable_website_url");
register_setting("anti_adblock_config_section", "alternative_ads_code");
register_setting("anti_adblock_config_section", "alternative_ads_selector_1");
register_setting("anti_adblock_config_section", "alternative_ads_code_1");
register_setting("anti_adblock_config_section", "alternative_ads_selector_2");
register_setting("anti_adblock_config_section", "alternative_ads_code_2");
register_setting("anti_adblock_config_section", "custom_css");
}
function disable_website_checkbox()
{
?>
<input type="checkbox" name="disable_website" value="1" <?php checked(1, get_option('disable_website'), true); ?> /> Check for Yes
<?php
}
function disable_website_image_input_field()
{
?>
<input name="disable_website_url" type="txt" value="<?php echo get_option('disable_website_url'); ?>" />
<?php
}
function alternative_ads_checkbox()
{
?>
<input type="checkbox" name="alternative_ads_code" value="1" <?php checked(1, get_option('alternative_ads_code'), true); ?> /> Check for Yes
<?php
}
function alternative_ads_selector_1_input_field()
{
?>
<input name="alternative_ads_selector_1" type="txt" value="<?php echo get_option('alternative_ads_selector_1'); ?>" />
<?php
}
function alternative_ads_code_1_input_field()
{
?>
<textarea name="alternative_ads_code_1"><?php echo get_option("alternative_ads_code_1"); ?></textarea>
<?php
}
function alternative_ads_selector_2_input_field()
{
?>
<input name="alternative_ads_selector_2" type="txt" value="<?php echo get_option('alternative_ads_selector_2'); ?>" />
<?php
}
function alternative_ads_code_2_input_field()
{
?>
<textarea name="alternative_ads_code_2"><?php echo get_option("alternative_ads_code_2"); ?></textarea>
<?php
}
function custom_css_input_field()
{
$css = ".anti-adblock-textarea{display: none}" . get_option("custom_css");
file_put_contents(plugin_dir_path(__FILE__) . "custom.css", $css);
?>
<textarea name="custom_css"><?php echo get_option("custom_css"); ?></textarea>
<?php
}
add_action("admin_init", "anti_adblock_settings");
Here’s what our settings page should look like:
This is where we can choose whether we want to display alternative ads or disable access to the website completely for users with AdBlock installed.
I am assuming that your website has two advertising placements. If you have more than this, add more fields to the settings page.
For alternative ads, you first need to provide the selector for the HTML element which holds the ads and then the ad code. Make sure that the ad code doesn’t have any advertising specific keywords or that their URL isn’t pointing to another advertising network. Otherwise they too, will get blocked. You can find selector of your ads container by inspecting the elements using your browser development tools. This will provide you with the class name or id of the HTML element.
Finally, we have an input box to add custom CSS to style the alternative ads. This CSS is flushed into a custom.css
file which will be embedded on the front end.
Passing Data from WordPress to JavaScript
We will be detecting AdBlock and then blocking or displaying alternative ads using JavaScript. To do this, we need to pass the data from the plugin settings to JavaScript.
There are various ways to pass data from WordPress to JavaScript, my preferred way is to pass it using HTML5 Data Attributes.
Place the following in the alternative.php
file.
function anti_adblock_footer_code()
{
if(get_option("disable_website") == 1)
{
?>
<span id="anti-adblock-disable-website" data-value="true"></span>
<span id="anti-adblock-disable-website-url" data-value="<?php echo get_option('disable_website_url'); ?>"></span>
<?php
}
else
{
?>
<span id="anti-adblock-disable-website" data-value="false"></span>
<?php
}
if(get_option("alternative_ads_code"))
{
//change this if your are adding more fields.
$count = 2;
?>
<span id="anti-adblock-alternative-ads" data-value="true" data-count="<?php echo $count; ?>"></span>
<?php
for($iii = 1; $iii <= $count; $iii++)
{
?>
<textarea class="anti-adblock-textarea" id="alternative_ads_selector_<?php echo $iii; ?>"><?php echo get_option("alternative_ads_selector_" . $iii); ?></textarea>
<textarea class="anti-adblock-textarea" id="alternative_ads_code_<?php echo $iii; ?>"><?php echo esc_html(get_option("alternative_ads_code_" . $iii)); ?></textarea>
<?php
}
}
else
{
?>
<span id="anti-adblock-alternative-ads" data-value="false"></span>
<?php
}
}
function anti_adblock_style_script()
{
wp_register_style("anti-adblock-custom", plugin_dir_url(__FILE__) . "custom.css");
wp_enqueue_style("anti-adblock-custom");
wp_enqueue_script('anti-adblock-script', plugin_dir_url(__FILE__) . "index.js", array("jquery"), '1.0.0', true);
}
add_action("wp_footer","anti_adblock_footer_code");
add_action("wp_enqueue_scripts", "anti_adblock_style_script");
Detecting AdBlock using JavaScript
There is no direct way to detect AdBlock using JavaScript. We have to create a sandbox environment using JavaScript and check if the testing advertisement banner is visible to the user or not.
Place the following JavaScript in the index.js
file, which is responsible for detecting the presence of AdBlock.
function adblock_detect() {
var iframe = document.createElement("iframe");
iframe.height = "1px";
iframe.width = "1px";
iframe.id = "ads-text-iframe";
iframe.src = "https://example.com/ads.html";
document.body.appendChild(iframe);
setTimeout(function() {
var iframe = document.getElementById("ads-text-iframe");
if (iframe.style.display == "none" || iframe.style.display == "hidden" || iframe.style.visibility == "hidden" || iframe.offsetHeight == 0) {
adblock_blocking_ads();
iframe.remove();
} else {
iframe.remove();
}
}, 100);
}
function adblock_blocking_ads(){}
Disabling the Website or Displaying Alternative Ads Using JavaScript
Once we’ve detected if AdBlock is blocking ads on our page, we need to act, based on our plugin settings.
Here’s the JavaScript code which disables the website or displays alternative ads based on our preferences.
Add the following code to the index.js
file.
function adblock_blocking_ads()
{
var blockwebsite = document.getElementById("anti-adblock-disable-website").getAttribute("data-value");
var alternativeads = document.getElementById("anti-adblock-alternative-ads").getAttribute("data-value");
if(blockwebsite == "true")
{
var url = document.getElementById("anti-adblock-disable-website-url").getAttribute("data-value");
document.body.innerHTML = "<div style='position: fixed; width: 100%; height: 100%; background-color:black; background-repeat: no-repeat; background-position: center center; background-image: url(" + url + ");'></div>";
}
else if(alternativeads == "true")
{
var count = document.getElementById("anti-adblock-alternative-ads").getAttribute("data-count");
for(var iii = 1; iii <= count; iii++)
{
var selector = document.querySelector("#alternative_ads_selector_" + iii).innerHTML;
if(selector != null)
{
document.querySelector(selector).innerHTML = htmlDecode(document.querySelector("#alternative_ads_code_" + iii).innerHTML);
}
}
}
}
function htmlDecode(input) {
var e = document.createElement('div');
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
window.addEventListener("load", function(){
adblock_detect();
}, false);
Our Complete Plugin Source Code
To recap, our plugin needs the following files:
--alternative -alternative.php -custom.css -index.js
Below is the complete source code for our AdBlock plugin.
alternative.php
<?php
/*
Plugin Name: Anti AdBlock
Plugin URI: https://www.sitepoint.com/
Description: This plugin lets you display alternative ads and also lets you disable website.
Version: 1.0
Author: Narayan Prusty
Author URI: http://qnimate.com
License: GPL2
*/
function add_anti_adblock_menu_item()
{
add_submenu_page("options-general.php", "Anti Adblock", "Anti Adblock", "manage_options", "anti-adblock", "anti_adblock_page");
}
function anti_adblock_page()
{
?>
<div class="wrap">
<h1>Anti Adblock</h1>
<form method="post" action="options.php">
<?php
settings_fields("anti_adblock_config_section");
do_settings_sections("anti-adblock");
submit_button();
?>
</form>
</div>
<?php
}
add_action("admin_menu", "add_anti_adblock_menu_item");
function anti_adblock_settings()
{
add_settings_section("anti_adblock_config_section", "", null, "anti-adblock");
add_settings_field("disable_website", "Do you want to disable website?", "disable_website_checkbox", "anti-adblock", "anti_adblock_config_section");
add_settings_field("disable_website_url", "Image to display when website is disabled", "disable_website_image_input_field", "anti-adblock", "anti_adblock_config_section");
add_settings_field("alternative_ads_code", "Do you want to display alternative ads code", "alternative_ads_checkbox", "anti-adblock", "anti_adblock_config_section");
add_settings_field("alternative_ads_selector_1", "Alternaive Ad Code 1 Selector", "alternative_ads_selector_1_input_field", "anti-adblock", "anti_adblock_config_section");
add_settings_field("alternative_ads_code_1", "Alternaive Ad Code 1", "alternative_ads_code_1_input_field", "anti-adblock", "anti_adblock_config_section");
add_settings_field("alternative_ads_selector_2", "Alternaive Ad Code 2 Selector", "alternative_ads_selector_2_input_field", "anti-adblock", "anti_adblock_config_section");
add_settings_field("alternative_ads_code_2", "Alternaive Ad Code 2", "alternative_ads_code_2_input_field", "anti-adblock", "anti_adblock_config_section");
add_settings_field("custom_css", "Custom CSS", "custom_css_input_field", "anti-adblock", "anti_adblock_config_section");
register_setting("anti_adblock_config_section", "disable_website");
register_setting("anti_adblock_config_section", "disable_website_url");
register_setting("anti_adblock_config_section", "alternative_ads_code");
register_setting("anti_adblock_config_section", "alternative_ads_selector_1");
register_setting("anti_adblock_config_section", "alternative_ads_code_1");
register_setting("anti_adblock_config_section", "alternative_ads_selector_2");
register_setting("anti_adblock_config_section", "alternative_ads_code_2");
register_setting("anti_adblock_config_section", "custom_css");
}
function disable_website_checkbox()
{
?>
<input type="checkbox" name="disable_website" value="1" <?php checked(1, get_option('disable_website'), true); ?> /> Check for Yes
<?php
}
function disable_website_image_input_field()
{
?>
<input name="disable_website_url" type="txt" value="<?php echo get_option('disable_website_url'); ?>" />
<?php
}
function alternative_ads_checkbox()
{
?>
<input type="checkbox" name="alternative_ads_code" value="1" <?php checked(1, get_option('alternative_ads_code'), true); ?> /> Check for Yes
<?php
}
function alternative_ads_selector_1_input_field()
{
?>
<input name="alternative_ads_selector_1" type="txt" value="<?php echo get_option('alternative_ads_selector_1'); ?>" />
<?php
}
function alternative_ads_code_1_input_field()
{
?>
<textarea name="alternative_ads_code_1"><?php echo get_option("alternative_ads_code_1"); ?></textarea>
<?php
}
function alternative_ads_selector_2_input_field()
{
?>
<input name="alternative_ads_selector_2" type="txt" value="<?php echo get_option('alternative_ads_selector_2'); ?>" />
<?php
}
function alternative_ads_code_2_input_field()
{
?>
<textarea name="alternative_ads_code_2"><?php echo get_option("alternative_ads_code_2"); ?></textarea>
<?php
}
function custom_css_input_field()
{
$css = ".anti-adblock-textarea{display: none}" . get_option("custom_css");
file_put_contents(plugin_dir_path(__FILE__) . "custom.css", $css);
?>
<textarea name="custom_css"><?php echo get_option("custom_css"); ?></textarea>
<?php
}
add_action("admin_init", "anti_adblock_settings");
function anti_adblock_footer_code()
{
if(get_option("disable_website") == 1)
{
?>
<span id="anti-adblock-disable-website" data-value="true"></span>
<span id="anti-adblock-disable-website-url" data-value="<?php echo get_option('disable_website_url'); ?>"></span>
<?php
}
else
{
?>
<span id="anti-adblock-disable-website" data-value="false"></span>
<?php
}
if(get_option("alternative_ads_code"))
{
//change this if your are adding more fields.
$count = 2;
?>
<span id="anti-adblock-alternative-ads" data-value="true" data-count="<?php echo $count; ?>"></span>
<?php
for($iii = 1; $iii <= $count; $iii++)
{
?>
<textarea class="anti-adblock-textarea" id="alternative_ads_selector_<?php echo $iii; ?>"><?php echo get_option("alternative_ads_selector_" . $iii); ?></textarea>
<textarea class="anti-adblock-textarea" id="alternative_ads_code_<?php echo $iii; ?>"><?php echo esc_html(get_option("alternative_ads_code_" . $iii)); ?></textarea>
<?php
}
}
else
{
?>
<span id="anti-adblock-alternative-ads" data-value="false"></span>
<?php
}
}
function anti_adblock_style_script()
{
wp_register_style("anti-adblock-custom", plugin_dir_url(__FILE__) . "custom.css");
wp_enqueue_style("anti-adblock-custom");
wp_enqueue_script('anti-adblock-script', plugin_dir_url(__FILE__) . "index.js", array("jquery"), '1.0.0', true);
}
add_action("wp_footer","anti_adblock_footer_code");
add_action("wp_enqueue_scripts", "anti_adblock_style_script");
index.js
function adblock_detect() {
var iframe = document.createElement("iframe");
iframe.height = "1px";
iframe.width = "1px";
iframe.id = "ads-text-iframe";
iframe.src = "https://example.com/ads.html";
document.body.appendChild(iframe);
setTimeout(function() {
var iframe = document.getElementById("ads-text-iframe");
if (iframe.style.display == "none" || iframe.style.display == "hidden" || iframe.style.visibility == "hidden" || iframe.offsetHeight == 0) {
adblock_blocking_ads();
iframe.remove();
}
else
{
iframe.remove();
}
}, 100);
}
function adblock_blocking_ads()
{
var blockwebsite = document.getElementById("anti-adblock-disable-website").getAttribute("data-value");
var alternativeads = document.getElementById("anti-adblock-alternative-ads").getAttribute("data-value");
if(blockwebsite == "true")
{
var url = document.getElementById("anti-adblock-disable-website-url").getAttribute("data-value");
document.body.innerHTML = "<div style='position: fixed; width: 100%; height: 100%; background-color:black; background-repeat: no-repeat; background-position: center center; background-image: url(" + url + ");'></div>";
}
else if(alternativeads == "true")
{
var count = document.getElementById("anti-adblock-alternative-ads").getAttribute("data-count");
for(var iii = 1; iii <= count; iii++)
{
var selector = document.querySelector("#alternative_ads_selector_" + iii).innerHTML;
if(selector != null)
{
document.querySelector(selector).innerHTML = htmlDecode(document.querySelector("#alternative_ads_code_" + iii).innerHTML);
}
}
}
}
function htmlDecode(input) {
var e = document.createElement('div');
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
window.addEventListener("load", function(){
adblock_detect();
}, false);
Screenshots
This is how it looks when you disable the whole website for AdBlock users.
This is how it looks when you want to display alternative ads.
A Word of Caution
As mentioned previously, when providing images when the website is disabled, make sure that the image URL doesn’t contain any ad specific keywords. Otherwise they will also get blocked.
Similarly, make sure alternate ads don’t point to any other advertising network or don’t point to URLs with ad specific keywords. Otherwise the alternate ads will also get blocked too. In this article, by alternate ads I’m referring to ads serverd from the same domain.
Final Thoughts
From my own analytics data I can say that 25% of website visitors use AdBlock. If you’re serving ads from ‘pay per impression’ networks then this plugin could increase your website revenue by 25% right away.
If you don’t want to block your site, then you can use the alternate ads feature to request the user to whitelist your website.