سؤال

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?

هل كانت مفيدة؟

المحلول

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).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى wordpress.stackexchange
scroll top