Add content between HTML paragraphs in WordPress posts

Looking for an automated way to add content, like ads or related posts, after paragraphs (<p></p>) in post content I found none that satisfied my needs completely. Creating a shortcode for this seems like an obvious candidate, but I really don’t like having to manually add shortcodes to content if there are other, more automated, methods available.

One of the solutions out there consists of splitting the content at every closing </p> tag, adding the content, and joining it all back together. Other solutions rely on regular expressions to find the paragraphs, which is known to be very problematic. So, none of the existing methods found really appealed to me. Let me explain why.

HTML, by nature, is a forgiving language that allows poor code to execute and render to varying levels of accuracy. This makes it a very difficult language to parse and manipulate correctly. Another difficulty is that (some) HTML elements are allowed to be nested inside other elements.

Let’s consider this valid HTML, where we want to add content (automatically) after a second paragraph.

<p>First paragraph</p>
<blockquote>
	<p>Second paragraph</p><!-- nested paragraph -->
</blockquote>
<p>Third paragraph</p>
<p>Fourth paragraph</p>

Using the above-mentioned methods the content is inserted after the <p> tag inside the <blockquote>. This is a problem because you probably didn’t want to include an ad (or other content) in your carefully crafted blockquote. Both methods are not context aware, they do not take into account if it’s a nested paragraph or not. This example shows how easily it could create problems, even with valid HTML.

And that’s why I’ve created a plugin to reliably insert content after top-level paragraphs only. It provides you with a function to help you insert content correctly in your (child) theme’s template files.

Click this link to download the plugin WP Insert Content or visit the GitHub repository for more information.

For those who want to know, it uses the PHP DOM module to parse the HTML.

Example

In this example we’re going to add content after the first paragraph in single post pages. The content we’re inserting is a link to a random post.

First activate the WP Insert Content plugin.

Note: It’s recommended you create a child theme first. If you upgrade the theme all our modifications (to insert the link) will be lost.

And put this in your (child) theme’s functions.php file

add_filter( 'the_content', 'insert_random_post_link_between_paragraphs' );

function insert_random_post_link_between_paragraphs( $content ) {

	// Check if the plugin WP Insert Content is activated.
	if ( !function_exists( 'keesiemeijer\Insert_Content\insert_content' ) ) {
		return $content;
	}

	// Check if we're inside the main loop in a single post page.
	if ( !( is_single() && in_the_loop() && is_main_query() ) ) {
		// Nope.
		return $content;
	}

	// Get a random post id.
	$args = array(
		'posts_per_page' => 1,
		'orderby'        => 'rand',
		'post__not_in'   => array( get_the_ID() ),
		'fields'         => 'ids',
	);

	$random_posts = get_posts( $args );

	// Check if a random post id was found.
	if ( isset( $random_posts[0] ) && $random_posts[0] ) {

		// Insert content after first top-level paragraph.
		$args = array(
			'insert_after_p' => 1,
		);

		// Create a link to the random post.
		$insert_content = '<a href=' . get_permalink( $random_posts[0] ) . '>' . get_the_title( $random_posts[0] ) . '</a>';

		// Insert the link after the first paragraph found in post content.
		$content = keesiemeijer\Insert_Content\insert_content( $content, $insert_content, $args );
	}

	return $content;
}

As you can see the plugin function insert_content() is used to add the link after the first paragraph.

		// Insert the link after the first paragraph found in post content.
		$content = keesiemeijer\Insert_Content\insert_content( $content, $insert_content, $args );

For more information about the insert_content() function see this repository that’s included in this plugin.

5 thoughts on “Add content between HTML paragraphs in WordPress posts

  1. This was just what I was looking for thanks.

    For future readers:

    I had to hack in the following code in insert-content.php to take care of special characters:

    // Load the HTML nodes from the content.
    @$nodes->loadHTML( ” . $content );

  2. // Load the HTML nodes from the content.

    @$nodes->loadHTML(  '<meta http-equiv="Content-Type" content="charset=utf-8" />' . $content );
  3. I used DomDocument for adding pictures with full page width from content editor. I added custom size into media uploader and if Domdocument finds image with that class it then adds needed HTML around that image.

  4. Hi @keesiemeijer, thank you for developing this plugin.

    After I installed the plugin, what code should I add to the functions.php? Can you please provide a sample code that adds after 1st paragraph?

    Thanks!

Leave a comment