Skip Navigation

[Résolu] Previous and Next Post Navigation when sorted by menu order

Ce fil est résolu. Voici une description du problème et la solution proposée.

Problem:
Display Post names in Previous and Next Post Navigation when sorted by menu order.
Expected Output:

 < Previous : Post Name | Post Name : Next >

Solution:

1. For this you should create custom shortcodes. Please add this code in your theme’s or child theme’s functions.php file:


add_shortcode( 'next_post', 'next_shortcode' );
function next_shortcode($atts) {
            global $post;
            ob_start();
            next_post_link( '<span class="nav-next">%link : Next ></span>', '%title' );
            $result = ob_get_contents();
            ob_end_clean();
            return $result;
}
  
add_shortcode( 'prev_post', 'prev_shortcode' );
            function prev_shortcode($atts) {
                        global $post;
                        ob_start();
                        previous_post_link( '<span class="nav-previous">< Previous : %link</span>', '%title' );
                        $result = ob_get_contents();
                        ob_end_clean();
            return $result;
}


// Customize Post Link Order
function my_custom_adjacent_post_where($sql) {
    if ( !is_main_query() || !is_singular() || 'playground' != get_post_type() )
        return $sql;
     
    $the_post = get_post( get_the_ID() );
    $patterns = array();
    $patterns[] = '/post_date/';
    $patterns[] = '/\'[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\'/';
    $replacements = array();
    $replacements[] = 'menu_order';
    $replacements[] = $the_post->menu_order;
    return preg_replace( $patterns, $replacements, $sql );
}
add_filter( 'get_next_post_where', 'my_custom_adjacent_post_where' );
add_filter( 'get_previous_post_where', 'my_custom_adjacent_post_where' );
function my_custom_adjacent_post_sort($sql) {
    if ( !is_main_query() || !is_singular() || 'playground' != get_post_type() )
        return $sql;
     
    $pattern = '/post_date/';
    $replacement = 'menu_order';
    return preg_replace( $pattern, $replacement, $sql );
}
add_filter( 'get_next_post_sort', 'my_custom_adjacent_post_sort' );
add_filter( 'get_previous_post_sort', 'my_custom_adjacent_post_sort' );

==> Whereas ‘playground’ is your custom post type slug, that you need to replace in the above code.

2. Then, add this shortcode in your Content Template to display Previous and Next post links:

[prev_post] | [next_post]

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

This topic contains 8 réponses, has 3 voix.

Last updated by Marcel Il y a 4 années et 5 mois.

Assigned support staff: Noman.

Auteur
Publications
#522429

I am trying to:
I want to show previous and next post in a content template for custom post type: 'playground' which are to be based on 'Menu Order' and not date.

There are two similar post on the subject:
https://toolset.com/forums/topic/create-next-link-link-child-previous-post-type/#post-287767
https://toolset.com/forums/topic/access-to-next-and-previous-pagepostcpt-links-and-fields/

Here is one such page: hidden link

At the end of the page, you will find list of all the posts for the post type 'playground' with their menu id (i have generated them using views).

I want to show < Previous : Post Name | Post Name : Next >

Kindly guide.

#522570

Noman
Supporter

Languages: Anglais (English )

Timezone: Asia/Karachi (GMT+05:00)

Hi Shreyas,

Thank you for contacting Toolset support.

1. Please add this code in your theme’s or child theme’s functions.php file:

add_shortcode( 'next_post', 'next_shortcode' );
function next_shortcode($atts) {
        	global $post;
        	ob_start();
        	next_post_link( '<span class="nav-next">%link : Next ></span>', '%title' );
        	$result = ob_get_contents();
        	ob_end_clean();
        	return $result;
}
 
add_shortcode( 'prev_post', 'prev_shortcode' );
        	function prev_shortcode($atts) {
                    	global $post;
                    	ob_start();
                    	previous_post_link( '<span class="nav-previous">< Previous : %link</span>', '%title' );
                    	$result = ob_get_contents();
                    	ob_end_clean();
        	return $result;
}

2. Add this shortcode in your Content Template:

[prev_post] | [next_post]

Please let me know if the above solution is fine or need any change.
Thank you

#522881

Dear Noman,

Thanks for sharing the code. However, it does work as expected. As written in my post query above, I actually wanted pagination to honour 'menu order'.

I am on page: Urban Flower Kandivali West - 50
50 being menu order
hidden link

I expect:
the previous link to show: Urban Flowers Ghatkopar East - 40 and
the next link to show: Urban Flower Opportunity School Chennai - 60

or vice a versa. Currently the pagination works on date chronological, which is the default behaviour.

Let me know if I have been able to clarify. Many thanks for looking into this. Look forward to hearing from you.

#522937

Noman
Supporter

Languages: Anglais (English )

Timezone: Asia/Karachi (GMT+05:00)

Hello Shreyas,

To debug this issue, I will need to take a look at your setup. So I need to request temporary access (WP-Admin and FTP Login info) to your staging site

Your next answer will be private which means only you and I have access to it.

=== Please backup your database and website ===

✙ I would additionally need your permission to de-activate and re-activate Plugins and the Theme, and to change configurations on the site. This is also a reason the backup is really important.

✙ Please add the Links to the [View] Edit Screen and [Content Template] Edit Screen where you have added this view.

Looking forward to help you, thank you

#522994

Noman
Supporter

Languages: Anglais (English )

Timezone: Asia/Karachi (GMT+05:00)

Hello Shreyas,

I have updated the the code in your theme’s functions.php file:

// Customize Post Link Order
function my_custom_adjacent_post_where($sql) {
	if ( !is_main_query() || !is_singular() )
		return $sql;
	
	$the_post = get_post( get_the_ID() );
	$patterns = array();
	$patterns[] = '/post_date/';
	$patterns[] = '/\'[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\'/';
	$replacements = array();
	$replacements[] = 'menu_order';
	$replacements[] = $the_post->menu_order;
	return preg_replace( $patterns, $replacements, $sql );
}
add_filter( 'get_next_post_where', 'my_custom_adjacent_post_where' );
add_filter( 'get_previous_post_where', 'my_custom_adjacent_post_where' );
function my_custom_adjacent_post_sort($sql) {
	if ( !is_main_query() || !is_singular() )
		return $sql;
	
	$pattern = '/post_date/';
	$replacement = 'menu_order';
	return preg_replace( $pattern, $replacement, $sql );
}
add_filter( 'get_next_post_sort', 'my_custom_adjacent_post_sort' );
add_filter( 'get_previous_post_sort', 'my_custom_adjacent_post_sort' );

Please check now, and let me know if any change is required.
Thank you

#523018

Dear Noman,

Thanks for the assistance. We're almost there.

While the pagination works fine and as per menu on the 'playground' post type, elsewhere they break.

Example:
'In the media' post type:
hidden link

hidden link (listing page)
The previous should show: Rondo
The next should show: Lebensart

Is there a way you can restrict trigger of the custom code that you have added to 'playground(s)' custom post type

#523075

Noman
Supporter

Languages: Anglais (English )

Timezone: Asia/Karachi (GMT+05:00)

Hello Shreyas,

I have updated / restricted the code and now it executes only on post type “Playground”. It is not affecting any other post type or any other pages.

// Customize Post Link Order
function my_custom_adjacent_post_where($sql) {
	if ( !is_main_query() || !is_singular() || 'playground' != get_post_type() )
		return $sql;
	
	$the_post = get_post( get_the_ID() );
	$patterns = array();
	$patterns[] = '/post_date/';
	$patterns[] = '/\'[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\'/';
	$replacements = array();
	$replacements[] = 'menu_order';
	$replacements[] = $the_post->menu_order;
	return preg_replace( $patterns, $replacements, $sql );
}
add_filter( 'get_next_post_where', 'my_custom_adjacent_post_where' );
add_filter( 'get_previous_post_where', 'my_custom_adjacent_post_where' );
function my_custom_adjacent_post_sort($sql) {
	if ( !is_main_query() || !is_singular() || 'playground' != get_post_type() )
		return $sql;
	
	$pattern = '/post_date/';
	$replacement = 'menu_order';
	return preg_replace( $pattern, $replacement, $sql );
}
add_filter( 'get_next_post_sort', 'my_custom_adjacent_post_sort' );
add_filter( 'get_previous_post_sort', 'my_custom_adjacent_post_sort' );

==> If you are having problems in ordering of these pages:
hidden link
hidden link

Then it's a separate thing and needs to be debugged separately, you can also check that after removing the code that we have added.

Thank you

#526500

Dear Noman,

Thanks for all your help. The code works as expected! Thanks a lot and apologies for delayed feedback.

#590932

Hi Norman

Thanks for this great piece of code. Works like a charm. I would like to extend it as follows.

I have a hierarchical CTP that has parent and child posts. Instead of a «next» link on the last of the child posts of a specific parent page I'd like to display text, eg. «end of chapter». How could I achieve this.

Thanks,
Marcel