add_filter(‘the_content’, ‘…’) stops pagination from working

I have a function (it deals with using preg_replace_callbackto replace Image URLs with URLs/paths to the uploads directory – lets call it replaceImgUrls()) which is then passed into add_filter('the_content', 'replaceImgUrls'). This works fine and stuff but on posts where I have added pagination (<!--nextpage-->), it stops this from working; it fails to split up the pages, but still shows the correct amount of page numbers at the bottom of the content, which you can still click on but each page shows the same content (i.e all the content which is in the post). Here is my function which replaces the image URLs:

add_filter('the_content', 'replaceImgURLS');
function replaceImgURLS($content) {
    global $post;
    $content = $post->post_content;
    $newContent = preg_replace_callback(
        '/<img.*src=['"]([^'"]*)/i', 
        function ($match) {
            global $post;
            $imgURL = $match[1];
            $filename   = basename($imgURL) . "-" . $post->ID . ".jpg"; // Create image file name
            $upload_dir = wp_upload_dir();
            $postMonth = mysql2date('m', $post->post_date);
            $postYear = mysql2date('Y', $post->post_date);
            $fileURL = $upload_dir['baseurl'] . '/' . $postYear . "/" . $postMonth . "/" . $filename;

            return '<img src="' . $fileURL;
        }, 
        $content
    );
    return $newContent;
}

When I remove this function from my functions.php file, the pagination is restored and works as it should (i.e each page is split up separately). I have wp_link_pages() in my content-single.php template file.

Read More

Thanks for any help 🙂

Related posts

Leave a Reply

2 comments

  1. For posts is set up by loop (see setup_postdata()) it is split into parts and array of those parts is assigned to global $pages variable. Even if it’s not paginated this is still where data goes.

    Then that variable is actually where get_the_content() looks for post content to process and output, not actual post object.

    In your function you are overriding $content filter gives you (properly truncated to the page necessary) with complete content from post object. Typically you should stick with acting on data filter gives you, accessing global scope instead of that is very prone to issues like this.

  2. Ok so I worked out what I had to do. @Rarst gave me some guidance which helped massively and I think his idea (in the comments of his question) would work but I haven’t actually tested it. Anyway, I fixed it by adding a $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; variable in, and, having changed $content = $post->post_content; to $content = get_the_content();, I passed $paged in as a variable, so it’s like this: $content = get_the_content($paged);. The final code which worked for me looks like this:

    add_filter('the_content', 'replaceImgURLS');
    function replaceImgURLS($content) {
        $post = get_post();
        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
        $content = get_the_content($paged);
        $newContent = preg_replace_callback(
            '/<img.*src=['"]([^'"]*)/i', 
            function ($match) {
                global $post;
                $imgURL = $match[1];
                $filename   = basename($imgURL) . "-" . $post->ID . ".jpg"; // Create image file name
                $upload_dir = wp_upload_dir();
                $postMonth = mysql2date('m', $post->post_date);
                $postYear = mysql2date('Y', $post->post_date);
                $fileURL = $upload_dir['baseurl'] . '/' . $postYear . "/" . $postMonth . "/" . $filename;
    
                return '<img src="' . $fileURL;
            }, 
            $content
        );
        return $newContent;
    }
    

    Hope that helps anyone who comes here by Google or anywhere else 🙂