WordPress: How To Insert An Ad Slot Halfway Into A Page Or Post

If you’ve been browsing my site this week, you may see some ads that don’t quite fit right. I’m working on getting everything working correctly and have most of it corrected. I’m doing this to increase monetization on the site rather than being dependent on Google Adsense and clogging your view of the content with pushy and obnoxious advertising.
One of the recommendations that was made to me was to insert an advertisement halfway through a blog post or page content. While that sounds easy, it can wreak havoc with column layouts or breaking up paragraphs. It’s not as simple as adding the total characters, dividing by two, and inserting the ad code. There are some additional exceptions:
- Headings – I don’t want an ad to follow a heading.
- Paragraphs – I want ads to be inserted after a paragraph is completed.
- Columns – I don’t want ads to be inserted within a column.
To do this, I added a function to functions.php
in my child theme to insert the ad slot within a page or post with the following code:
function insert_ad_middle($content) {
$ad_code = NETPEAK_MIDDLE_AD_CODE;
if (is_single() || is_page() || get_post_type() == 'acronym') {
// Extract 'wp-block-columns' divs
preg_match_all('/<div[^>]*class="[^"]*wp-block-columns[^"]*"[^>]*>.*?<\/div>/s', $content, $matches);
$columns_content = $matches[0];
$placeholder = "<!--WPBLOCKCOLUMNS-->";
$content_with_placeholders = preg_replace('/<div[^>]*class="[^"]*wp-block-columns[^"]*"[^>]*>.*?<\/div>/s', $placeholder, $content);
// Split content by all HTML tags, but keep the tags in the results
$split_content = preg_split('/(<[^>]*>)/', $content_with_placeholders, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$total_length = array_sum(array_map('mb_strlen', $split_content)); // Total length of text without HTML tags
$half_length = $total_length / 2;
// Find the position to insert ad based on text content length
$current_length = 0;
$insert_pos = 0;
foreach ($split_content as $index => $fragment) {
// Skip HTML tags for length calculation
if (!preg_match('/<[^>]+>/', $fragment)) {
$current_length += mb_strlen($fragment);
}
// Check if current position is past half the total length
if ($current_length >= $half_length) {
$insert_pos = $index;
break;
}
}
// Adjust insertion position to place ad outside of HTML tags
while ($insert_pos > 0 && preg_match('/<[^>]+>/', $split_content[$insert_pos])) {
$insert_pos--; // Move back to find position outside HTML tags
}
// Reassemble content with ad inserted
array_splice($split_content, $insert_pos + 1, 0, $ad_code);
$content_with_ad = implode('', $split_content);
// Reinsert 'wp-block-columns' divs
foreach ($columns_content as $div) {
$content_with_ad = preg_replace('/' . preg_quote($placeholder, '/') . '/', $div, $content_with_ad, 1);
}
return $content_with_ad;
}
return $content;
}
add_filter('the_content', 'insert_ad_middle');
How This Works:
- Content Division: The content is split into parts, keeping HTML tags separate from text content. This allows us to measure the length of the actual text content, ignoring HTML tags, and find the middle of the text.
- Ad Placement: The function calculates where the middle of the non-tag content is and places the ad just before the next HTML tag encountered after the middle of the text. This ensures that the ad is not placed within any HTML tags.
- Reassembling Content: After inserting the ad, the function reassembles the content, including all HTML tags and the
wp-block-columns
divs in their original order.
This code is useful for dynamically placing ads within the content, potentially increasing engagement and revenue. Using a fallback mechanism ensures that ads will always be displayed, maximizing the opportunity for ad views and clicks even if a suitable location isn’t found with the logic above.