Last active
February 26, 2026 01:44
-
-
Save Jeradin/b01b3b68ff7b69d957d848fa519a5d66 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Get single entry pagination links | |
| * to use: call anagram_entry_pagintion(); | |
| * | |
| */ | |
| function anagram_entry_pagintion() { | |
| global $gravityview_view; | |
| $criteria['paging'] = array( | |
| 'offset' => 0, | |
| 'page_size' => 200 | |
| ); | |
| $criteria['sorting'] = array( | |
| 'key' => $gravityview_view->atts['sort_field'], | |
| 'direction' => $gravityview_view->atts['sort_direction'] | |
| ); | |
| //Using this below to get all entry IDs, I know there is a direct function for that, but wanted to preserve the Views sort order. | |
| $entry_ids = wp_list_pluck( gravityview_get_entries( $gravityview_view->form_id , $criteria, $sorting ), 'id' ); | |
| $total_count = count($entry_ids); | |
| $current_entry = get_query_var( 'entry' ); | |
| $position = array_search($current_entry, $entry_ids); | |
| $prev_pos = ! rgblank( $position ) && $position > 0 ? $position - 1 : false; | |
| $next_pos = ! rgblank( $position ) && $position < $total_count - 1 ? $position + 1 : false; | |
| $post_id = $gravityview_view->getPostId(); | |
| $query_arg_name = GravityView_Post_Types::get_entry_var_name(); | |
| $output = '<ul class="list-inline">'; | |
| $output .= '<li class="gf_entry_count">'; | |
| $output .= '<span>entry <strong>'. ($position + 1) .'</strong> of <strong>'. $total_count .'</strong></span>'; | |
| $output .= '</li>'; | |
| $output .= '<li class="gf_entry_prev gv_pagination_links">'; | |
| $output .= '<a href="' . GravityView_API::entry_link( $entry_ids[$prev_pos] ) . '" class="' . ($prev_pos !== false ? ' ' : ' gf_entry_disabled') . '" title="Previous Entry"><i class="fa-lg fa fa-arrow-circle-o-left"></i></a></li>'; | |
| $output .= '</li>'; | |
| $output .= '<li class="gf_entry_next gv_pagination_links">'; | |
| $output .= '<a href="' . GravityView_API::entry_link( $entry_ids[$next_pos] ) . '" class="' . ($next_pos !== false ? ' ' : ' gf_entry_disabled') . '" title="Next Entry"><i class="fa-lg fa fa-arrow-circle-o-right"></i></a></li>'; | |
| $output .= '</li>'; | |
| $output .= '</ul>'; | |
| return $output; | |
| } |
Hi @Jeradin, this is catching all entries in my form, including trashed entries, and entries that have not been approved (this is relevant if a view is set to only show approved entries). Any ideas ?
Updated snippet that works with GravityView 2+:
- Uses the modern
gravityview()->requestAPI instead of the deprecatedglobal $gravityview_view - Respects the View's "Show Only Approved" setting
- Only includes active (non-trashed) entries
- Follows the View's configured sort order
- Hides the Previous link on the first entry and the Next link on the last entry
- Escapes all URLs for security
- Works with both CPT Views and shortcode-embedded Views
Note: if you have more than 500 entries in a View, increase the page_size value.
<?php
/**
* GravityView Single Entry Navigation
*
* Adds "Entry X of Y" with Previous/Next links on single entry views.
* Respects View sorting, approval status, active entry filters, and Advanced Filter conditions.
*
* Works with both CPT Views and shortcode-embedded Views.
*
* Usage: add this to your theme's functions.php or as a code snippet plugin.
* The navigation will automatically appear at the bottom of single entry views.
*/
/**
* Get single entry pagination links for GravityView 2.x+.
*
* @param \GV\Template_Context $context The template context provided by GravityView.
*
* @return string HTML output with entry count and navigation links.
*/
function gv_single_entry_navigation( $context ) {
$view = $context->view;
$entry = $context->entry;
if ( ! $view instanceof \GV\View || ! $view->form || ! $entry ) {
return '';
}
// Override paging to retrieve ALL entries (not just one page).
// Uses the View's full entry pipeline, which fires `gravityview/view/query`
// so Advanced Filter, approval status, sorting, etc. are all applied.
$remove_limit = function ( &$query ) {
$query->limit( 5000 )->offset( 0 );
};
add_action( 'gravityview/view/query', $remove_limit, 9999 );
$entries = $view->get_entries( gravityview()->request );
remove_action( 'gravityview/view/query', $remove_limit, 9999 );
$all_entries = $entries->all();
if ( empty( $all_entries ) ) {
return '';
}
// Find the current entry position in the sorted, filtered list.
$current_id = $entry->ID;
$total_count = count( $all_entries );
$position = false;
foreach ( $all_entries as $index => $gv_entry ) {
if ( (string) $gv_entry->ID === (string) $current_id ) {
$position = $index;
break;
}
}
if ( false === $position ) {
return '';
}
$prev_pos = $position > 0 ? $position - 1 : false;
$next_pos = $position < $total_count - 1 ? $position + 1 : false;
$output = '<div class="gv-entry-navigation" style="margin: 1em 0; display: flex; align-items: center; gap: 1em;">';
if ( false !== $prev_pos ) {
$prev_link = GravityView_API::entry_link( $all_entries[ $prev_pos ]->as_entry() );
$output .= '<a class="gv-entry-prev" href="' . esc_url( $prev_link ) . '">← Previous</a>';
}
$output .= '<span class="gv-entry-count">Entry <strong>' . ( $position + 1 ) . '</strong> of <strong>' . $total_count . '</strong></span>';
if ( false !== $next_pos ) {
$next_link = GravityView_API::entry_link( $all_entries[ $next_pos ]->as_entry() );
$output .= '<a class="gv-entry-next" href="' . esc_url( $next_link ) . '">Next →</a>';
}
$output .= '</div>';
return $output;
}
// Output navigation at the bottom of single entry views.
add_action( 'gravityview/template/after', function ( $context ) {
if ( ! $context instanceof \GV\Template_Context ) {
return;
}
if ( ! $context->entry ) {
return;
}
echo gv_single_entry_navigation( $context );
} );
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you @Jeradin!