0

I have a function that makes the post multipage based on a URL Parameter with a specific value:

?content=multipage

The problem is that when a user clicks to the next page the URL parameter is stripped and the post resets to the onepage format.

If I manually add the URL parameter to the next page the post is multipage

From my research the best way to solve the problem is by setting a cookie when:

?content=multipage

That way this URL parameter gets passed on from page to page and it won't be visible in the address bar.

I tried multiple cookie setting methods, I found secookie () function that apparently should do the trick.

Here is my work so far:

    function onepage() {
    //**Removes shortcodes**//
    function remove_shotcode($content) {
        return str_replace('[/shortcode1]', '', $content);    
        return str_replace('[shortcode2]', '', $content);
    }
    add_filter( 'the_content', 'remove_shotcode'); 

/*
*Removes <!--nextpage-->
*@see http://wordpress.stackexchange.com/a/183587/26350
*/

    add_action( 'the_post', function( $post )
    {
        if ( false !== strpos( $post->post_content, '<!--nextpage-->' ) ) 
        {
            // Reset the global $pages:
            $GLOBALS['pages']     = [ $post->post_content ];

            // Reset the global $numpages:
            $GLOBALS['numpages']  = 0;

           // Reset the global $multipage:
            $GLOBALS['multipage'] = false;
        }

    });
    }

    //**IF Statement that should set the cookie**//
    if ( empty( $_GET['content'] ) || "multipage" !== $_GET['content'] ) {
        //**Only removes onepage() when content=multipage**//
        add_action('wp','onepage');
        //**Should set cookie only when content=multipage**//
        setcookie( 'content', 'multipage', time()+3600, COOKIEPATH, COOKIE_DOMAIN );
    }

The code that makes the post multipage is below:


    //**PAGEBREAK SECTION - BEG**//
    function pagebreak( $args = '' ) {
        global $page, $numpages, $multipage, $more;

        $defaults = array(
            'before'           => '<p class="post-nav-links">' . __( 'Pages:' ),
            'after'            => '</p>',
            'link_before'      => '',
            'link_after'       => '',
            'aria_current'     => 'page',
            'next_or_number'   => 'next',
            'separator'        => ' ',
            'nextpagelink'     => __( 'Next page' ),
            'eog'              => '<a href="http://127.0.0.1:10080/wordpress/">',
            'previouspagelink' => __( 'Previous page' ),
            'pagelink'         => '%',
            'echo'             => 1,
        );

        $params = wp_parse_args( $args, $defaults );

        /**
         * Filters the arguments used in retrieving page links for paginated posts.
         *
         * @since 3.0.0
         *
         * @param array $params An array of arguments for page links for paginated posts.
         */
        $r = apply_filters( 'wp_link_pages_args', $params );

        $output = '';
        if ( $multipage ) {
            if ( 'number' == $r['next_or_number'] ) {
                $output .= $r['before'];
                for ( $i = 1; $i <= $numpages; $i++ ) {
                    $link = $r['link_before'] . str_replace( '%', $i, $r['pagelink'] ) . $r['link_after'];
                    if ( $i != $page || ! $more && 1 == $page ) {
                        $link = _wp_link_page( $i ) . $link . '</a>';
                    } elseif ( $i === $page ) {
                        $link = '<span class="post-page-numbers current" aria-current="' . esc_attr( $r['aria_current'] ) . '">' . $link . '</span>';
                    }
                    /**
                     * Filters the HTML output of individual page number links.
                     *
                     * @since 3.6.0
                     *
                     * @param string $link The page number HTML output.
                     * @param int    $i    Page number for paginated posts' page links.
                     */
                    $link = apply_filters( 'wp_link_pages_link', $link, $i );

                    // Use the custom links separator beginning with the second link.
                    $output .= ( 1 === $i ) ? ' ' : $r['separator'];
                    $output .= $link;
                }
                $output .= $r['after'];
            } elseif ( $more ) {
                $output .= $r['before'];
                $prev    = $page - 1;

                $next = $page + 1;
                if ( $next <= $numpages ) {
                    if ( $prev ) {
                        $output .= $r['separator'];
                    }
                    $link = _wp_link_page( $next ) . $r['link_before'] . $r['nextpagelink'] . $r['link_after'] . '</a>';

                    /** This filter is documented in wp-includes/post-template.php */
                    $output .= apply_filters( 'wp_link_pages_link', $link, $next );
                }           elseif ( $next  = $numpages ) {
                $link = _wp_link_page( $next ) . $r['eog'] . $r['nextpagelink'] . $r['link_after'] . '</a>';
                }


                $output .= $r['after'];
            }
        }

        /**
         * Filters the HTML output of page links for paginated posts.
         *
         * @since 3.6.0
         *
         * @param string $output HTML output of paginated posts' page links.
         * @param array  $args   An array of arguments.
         */
        $html = apply_filters( 'wp_link_pages', $output, $args );

        if ( $r['echo'] ) {
            echo $html;
        }
        return $html;
    }

    /**
     * Replace [nextpage] with <!--nextpage--> through the 'the_posts' filter.
     *
     * @see http://wordpress.stackexchange.com/a/183980/26350
     */

    ! is_admin() && add_filter( 'the_posts', function( $posts )
    {
        $posts = array_map( function( $p )
        {
            if ( false !== strpos( $p->post_content, '[pagebreak]' ) )
                $p->post_content = str_replace( '[pagebreak]', '<!--nextpage-->', $p->post_content ); 
            return $p;
        }, $posts );
        return $posts;
    });
    //**PAGEBREAK SECTION - END**//

I looked in the cookie list of my browser and apparently this does set the cookie content to value multipage.

However, it seems that it sets the cookie whether the URL has the URL parameter or not.

And when I go to the next page, the layout resets to onepage so I am assuming the site does not read the cookie.

Is it possible to store the ?content=multipage in the cookie so that site becomes multipage for that user or the ?content=multipage has to be passed from page to page?

2
  • 1
    Cookies aren't a good choice here. It means you can't use caching because PHP needs to run to evaluate the cookie and generate the page for each user. The best solution would either be to add the query parameter to the pagination links, as you've tried, or use the pagination URL to also set the post to multipage mode. If you can include the code you use to make the page multipage using the URL parameter it will be easier to help. Commented Aug 7, 2019 at 8:26
  • Thanks! I might be wrong but the one problem I see with your solution is that if a user chooses to go to another post it won't be multipage anymore because only the nextpage button of post X will have the URL parameter and it wont be passed to post Y. Is there a way to bypass that so that for at least the remainder of the session all posts will be multipage?
    – Discover
    Commented Aug 7, 2019 at 16:29

1 Answer 1

0

I agree that passing the query string from one page to another page is the most reliable solution, and you can, for example, use filters like post_link and term_link to add the content query string to post/category links.

However, it requires hooking to various filters like you can see here. And in addition, multi-page URLs like example.com/page/2?content=multipage won't work without extra coding.

So it's probably better/easier for you to store the multi-page status in the browser's cookies, just as what you've attempted — the problem in your code is, that you're just setting the cookie, but nowhere reading it. And you can use $_COOKIE['content'] to read the cookie's value, just as you can see in the example below.

The Code/Solution

First off, remove this from your code:

//**IF Statement that should set the cookie**//
if ( empty( $_GET['content'] ) || "multipage" !== $_GET['content'] ) {
    //**Only removes onepage() when content=multipage**//
    add_action('wp','onepage');
    setcookie( 'content', 'multipage', time()+3600, COOKIEPATH, COOKIE_DOMAIN );
}

And add the code after the //**PAGEBREAK SECTION - END**// in your code:

add_action( 'init', 'set_check_content_cookie', 0 );
function set_check_content_cookie() {
    if ( is_admin() ) {
        return;
    }

    $is_multipage = false;
    // If the query string "content" is not set, check if the "content" cookie value is exactly "multipage".
    if ( ! isset( $_GET['content'] ) && isset( $_COOKIE['content'] ) && 'multipage' === $_COOKIE['content'] ) {
        $is_multipage = true;
    }
    // If the query string "content" is set and its value is "multipage", set the cookie.
    elseif ( isset( $_GET['content'] ) && 'multipage' === $_GET['content'] ) {
        setcookie( 'content', 'multipage', time()+3600, COOKIEPATH, COOKIE_DOMAIN );
        $is_multipage = true;
    }

    // Hook onepage() to `wp`, if applicable.
    if ( ! $is_multipage ) {
        add_action( 'wp', 'onepage' );
    }
}

Note: You should remember that using this solution means that cookies must be enabled in the browser (i.e. supported and that the user is accepting cookies).

2
  • I hope you don't mind I re-posted the answer as a new answer, and let me know how it goes. :)
    – Sally CJ
    Commented Aug 10, 2019 at 11:53
  • 1
    Amazing! Works wonderfully!
    – Discover
    Commented Aug 10, 2019 at 23:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.