Skip to content

Instantly share code, notes, and snippets.

@wisnust
Forked from allenbell/pagination.php
Created February 16, 2021 16:41
Show Gist options
  • Save wisnust/fd7b699246c69574d97a5cbc03e081d3 to your computer and use it in GitHub Desktop.
Save wisnust/fd7b699246c69574d97a5cbc03e081d3 to your computer and use it in GitHub Desktop.
Ajax pagination for posts linked via ACF Relationships
<?php
function ajax_pagination_enqueue() {
// Register and enqueue our javascript file
wp_register_script( 'pagination',
get_template_directory_uri() . '/library/js/pagination.js', // or wherever you put the file in your theme directory
array('jquery'));
wp_enqueue_script('pagination');
// Connect to WordPress' built-in Ajax file
wp_localize_script( 'pagination', 'ajaxpagination', array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
));
}
add_action( 'wp_enqueue_scripts', 'ajax_pagination_enqueue' );
// Hook this function to WordPress' Ajax actions
add_action( 'wp_ajax_nopriv_dl_bike_features', 'dl_bike_features' );
add_action( 'wp_ajax_dl_bike_features', 'dl_bike_features' );
function dl_bike_features() {
global $post;
if ($post->ID) {
// On initial page load, just grab the post ID...
$bike_id = $post->ID;
} else {
// ... but once you're using Ajax, need to get the ID via Ajax
$bike_id = $_POST['bikeID'];
}
if (isset($_POST['page'])) {
// Set $page to data from Ajax, if available
$page = $_POST['page'];
} else {
// ... if not, set default to 1 (for initial page load)
$page = 1;
}
// Set up $current_page to calculate page for previous / next buttons
if (!empty($page)) {
$current_page = intval($page);
}
// $page is coming from the href, so need to extract the page from the url
$tens = substr($page, -3, 1);
$hundreds = substr($page, -4, 1);
/*
** If the character 3 or 4 spaces back from the end is not a number,
** intval will convert it to 0, which will test as false in the if statements below
*/
$tens = intval($tens);
$hundreds = intval($hundreds);
if ($hundreds) {
$page = intval(substr($page, -4, 3));
} elseif ($tens) {
$page = intval(substr($page, -3, 2));
} else { // single digit
$page = intval(substr($page, -2, 1));
}
// Get all posts that are linked to the current post via ACF Relationship
$features = get_posts(array(
// post type of the posts linked to current post
'post_type' => 'bike-features',
// fetch all of them--we'll divide them into separate pages in a moment
'posts_per_page' => -1,
'meta_query' => array(
array(
// name of ACF Relationship field
'key' => 'bikes_with_this_feature',
// ID of current post
'value' => $bike_id,
'compare' => 'LIKE'
)
)
));
// Pagination variables
$feature_count = 0;
$features_per_page = 16; // How many features to display on each page
$total = count( $features );
$pages = ceil( $total / $features_per_page );
$min = ( ( $page * $features_per_page ) - $features_per_page ) + 1;
$max = ( $min + $features_per_page ) - 1;
if( $features ) {
// Iterator for rows
$i = 1;
?>
<div id="bike-features-container">
<div id="bike-features-inner">
<div class="bike-features-content">
<!-- Note: using Bootstrap grid -->
<div class="row">
<?php foreach( $features as $feature ) {
$feature_count++;
// Ignore this feature if $feature_count is lower than $min
if($feature_count < $min) { continue; }
// Stop loop completely if $feature_count is higher than $max
if($feature_count > $max) { break; }
?>
<div class="col-xs-6 col-sm-3">
<article id="post-<?php echo $feature->ID; ?>" <?php post_class('clearfix bike-features'); ?> role="article">
<?php echo $feature->post_title; ?>
</article> <!-- end article -->
</div>
<?php
// Start a new row after every 4 posts
if ($i % 4 == 0) {
echo '</div><!-- .row --><div class="row">';
}
$i++;
};
?>
</div><!-- .row -->
</div><!-- .bike-features-content -->
<div id="pagination">
<?php
// Ajax will grab the post ID from here.
echo '<span id="bike-id" data-bike-id="' . $bike_id . '"></span>';
// Pagination
$prev = ($current_page - 1);
$next = ($current_page + 1);
$pagination = paginate_links( array(
'base' => get_permalink() . '%#%' . '/',
'format' => '?page=%#%',
'current' => $page,
'total' => $pages,
'prev_text' => '&lsaquo;',
'next_text' => '&rsaquo;',
'type' => 'plain',
) );
echo $pagination;
?>
</div> <!-- #pagination -->
</div> <!-- #bike-features-inner -->
</div> <!-- #bike-features-container -->
<?php } // end if ($features)
wp_reset_postdata();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment