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
*/
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
*/
! 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 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/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/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?
1 Answer
Reset to default 0I 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/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).
multipage
anymore because only thenextpage
button ofpost X
will have the URL parameter and it wont be passed topost Y
. Is there a way to bypass that so that for at least the remainder of the session all posts will bemultipage
? – Discover Commented Aug 7, 2019 at 16:29