Skip to content

Instantly share code, notes, and snippets.

@Jeradin
Last active February 26, 2026 01:44
Show Gist options
  • Select an option

  • Save Jeradin/b01b3b68ff7b69d957d848fa519a5d66 to your computer and use it in GitHub Desktop.

Select an option

Save Jeradin/b01b3b68ff7b69d957d848fa519a5d66 to your computer and use it in GitHub Desktop.
/**
* 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;
}
@usefulartservices
Copy link

Thank you @Jeradin!

@usefulartservices
Copy link

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 ?

@mrcasual
Copy link

mrcasual commented Feb 10, 2026

Updated snippet that works with GravityView 2+:

  • Uses the modern gravityview()->request API instead of the deprecated global $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 ) . '">&larr; 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 &rarr;</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