Automatically add after X number of paragraphs

The concept

Adding something to the content during saving and considering all sorts of possible MarkUp isn’t an easy task. I played around a bit with it and decided that the best chance would be to use PHP native \DOMDocument class to parse the content, identify the paragraph and add the HTML comment to it. This is much more reliable than using Regular Expressions and much better performance wise.

Adjusting the plugin

First, the plugin uses Dependency Injection to decouple the classes. If you need to alter the output (change the number of paragraphs, insert some other comment like a line break or something from a shortcode, etc.), you’ll need to jump in and adjust the arguments for the Parser class that is initialized from inside the Controller.

If you want to insert some normal HTML (for example an ad after the X paragraph), then you’ll need to go into the Parser and remove the following line:

$comment = $this->dom->appendChild( new \DOMComment( $this->tag ) );

and then replace the $comment in the next line with $this->tag. Then you can throw in normal HTML tags, text or whatever.

For more complicated stuff, you’ll need to utilize the DOMDocument and similar object methods. Please refer to php.net for further information.

Notes

The following plugin only works with PHP 5.3+. If you got an earlier version, it simply won’t activate and instead show you a WP die screen.

The plugin

<?php
namespace WPSE\NextpageParagraph107787;

defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (#107787) Nextpage after X paragraphs
 * Plugin URl:  http://wordpress.stackexchange.com/questions/107787
 * Description: <strong>Needs PHP 5.3+!</strong> Adds a <code><!--nextpage--></code> tag after X paragraphs.
 * Author:      Franz Josef Kaiser
 * Author URl:  http://unserkaiser.com
 * License:     MIT
 */

\add_action( 'init', array( __NAMESPACE__.'\Controller', 'init' ) );
class Controller
{
    protected static $instance = null;

    public static function init()
    {
        null === self::$instance AND self::$instance = new self;
        return self::$instance;
    }

    protected function __construct()
    {
        $parser = new Parser();
        $parser->setTag( 'nextpage' );
        $parser->setTagAmount( 5 );

        \add_action( 'load-post.php', array( $parser, 'onSave' ) );
        \add_action( 'load-post-new.php', array( $parser, 'onSave' ) );
    }
}

class Parser
{
    private $dom    = null;
    private $tag    = null;
    private $amount = null;

    public function __construct( $tag = null, $paragraph_number = null )
    {
        null === $this->dom
            AND $this->dom = new \DOMDocument();
    }

    public function setTag( $tag )
    {
        $this->tag = $tag;
    }

    public function setTagAmount( $amount )
    {
        $this->amount = $amount;
    }

    public function onSave( $post_id )
    {
        if ( empty( $_POST['content'] ) )
            return;

        $this->dom->loadHTML( \wpautop( $_POST['content'] ) );
        $paragraph = $this->dom->getElementsByTagName( 'p' );

        $content = null;
        $i = 1;
        foreach ( $paragraph as $p )
        {
            $content .= $this->dom->saveHTML( $p );
            if (
                $this->amount === $i++
                AND $this->amount < $paragraph->length
                )
            {
                $comment = $this->dom->appendChild( new \DOMComment( $this->tag ) );
                $content .= $this->dom->saveHTML( $comment );
            }
        }

        // Add to the HTTP $_POST global
        $_POST['content'] = $content;
    }
}

\register_activation_hook( __FILE__, array( __NAMESPACE__.'\Setup', 'onActivation' ) );    
\register_deactivation_hook( __FILE__, array( __NAMESPACE__.'\Setup', 'onDeactivation' ) );    
\register_activation_hook( __FILE__, array( __NAMESPACE__.'\Setup', 'onUninstall' ) );
class Setup
{
    public function onActivation()
    {
        if ( ! current_user_can( 'activate_plugins' ) )
            return;
        $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
        check_admin_referer( "activate-plugin_{$plugin}" );

        // do stuff
    }

    public function onDeactivation()
    {
        if ( ! current_user_can( 'activate_plugins' ) )
            return;
        $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
        check_admin_referer( "deactivate-plugin_{$plugin}" );

        // do stuff
    }

    public function onUninstall()
    {
        if ( ! current_user_can( 'activate_plugins' ) )
            return;
        check_admin_referer( 'bulk-plugins' );

        if ( __FILE__ != WP_UNINSTALL_PLUGIN )
            return;

        // do stuff
    }
}

Leave a Comment