Insert an Ad or Call to Action in The Middle of a WordPress Post

James Parsons by James Parsons Updated Feb 6th, 2024 2 Comments•

Have you ever seen a post that had an advertisement or a call to action half-way through or 30% through the blog post? Sure you have. If not, you can see one on any of our blog posts, like this one.

Here's how to do it. Add this to your functions.php file in your theme:

/**
 * Insert call to action to middle of blog posts
 */
 
add_filter('the_content', 'prefix_insert_post_ads');
function prefix_insert_post_ads($content) {
	if (strpos($_SERVER['REQUEST_URI'], '/glossary/') !== false) { // Ignore on custom post types, optional
		return $content;
	}
	$ad_code = '
	
	  <div id="middle-post-cta">
		  <!-- Add your call to action HTML here -->
	  </div>
	  
	  ';
	if (is_single() && !is_admin() && !is_single(1234)) { // Exclude post ID(s) here, optional
		return prefix_insert_after_paragraph($ad_code, $content);
	}
	return $content;
}
function prefix_insert_after_paragraph( $insertion, $content ) {
	$doc = new DOMDocument();
	@$doc->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'));
	$paragraphs = $doc->getElementsByTagName('p');
	$targetParagraphId = round($paragraphs->length / 2);
	$totalParagraphs = $paragraphs->length;
	$inserted = false;
	while(!$inserted && $targetParagraphId < $totalParagraphs) {
		$paragraph = $paragraphs->item($targetParagraphId);
		$parentTag = $paragraph->parentNode->nodeName;
		if ( $parentTag != 'blockquote' && $parentTag != 'ul' && $parentTag != 'ol' && $parentTag != 'li' && !$inserted){
			$newNode = $doc->createDocumentFragment();
			$newNode->appendXML($insertion);
			$paragraph->parentNode->insertBefore($newNode, $paragraph);
			$inserted = true;
		}
		$targetParagraphId++;
	}
	$body = $doc->getElementsByTagName('body')->item(0);
	return $doc->saveHTML($body);
}

There's a few parts to this.

First, you have the ability to ignore this on certain categories or custom post types by adding a URL pattern to ignore. In this code, you'll see we have our /glossary/ custom post type as an example, since we don't want to put call to actions on these shorter posts.

If you don't need this part, simply comment out these three lines for now:

// if (strpos($_SERVER['REQUEST_URI'], '/glossary/') !== false) { // Ignore on custom post types, optional
//     return $content;
// }

Next, excluding post IDs. This is if you have a special post that you want to keep advertisement-free. You can add the post ID here (replace 1234 with the post ID), and it will add it to all posts except for that one post:

if (is_single() && !is_admin() && !is_single(1234)) {

Or, if you want to add multiple:

if (is_single() && !is_admin() && !is_single(1234) && !is_single(1235) && !is_single(1236)) {

Or, if you have an entire category that you want to skip, you can use:

if (is_single() && !is_admin() && !has_category('Fishing')) { // Replace with your category

Lastly, this line is what controls where the call to action is inserted. I have it set to insert it half way through the post, so I divide the post by 2 and round to the nearest paragraph:

$paragraph_id = round(count($paragraphs) / 2);

But, if you want to make it appear earlier in the article, you can make it show up 33% through the article by dividing by 3 instead:

$paragraph_id = round(count($paragraphs) / 3);

This code is also configured to ignore blockquote, ul, li, and ol tags. You don't want it adding your HTML code inside a bullet point list or within a quote, after all!

I hope this helps! Please let me know if you have any questions in the comments and I'll get back to you very quickly.

Related Code Snippets

Written by James Parsons

James Parsons is the founder and CEO of Content Powered, a premier content marketing agency that leverages nearly two decades of his experience in content marketing to drive business growth. Renowned for founding and scaling multi-million dollar eCommerce businesses through strategic content marketing, James has become a trusted voice in the industry, sharing his insights in Search Engine Watch, Search Engine Journal, Forbes, Entrepreneur, Inc, and other leading publications. His background encompasses key roles across various agencies, contributing to the content strategies of major brands like eBay and Expedia. James's expertise spans SEO, conversion rate optimization, and effective content strategies, making him a pivotal figure in the industry.