I've created a clone of the core Recent Posts widget as suggested here Code for Recent Posts Widget, but how would I go about adding pagination to that widget?
I intend on using auto-pagination for infinite scroll, but I'm not sure where to start...
Using Wordpress 3.9.1 so the most popular widget pagination plugin isn't compatible.
I added this:
function my_app_latest_add_query_var() {
global $wp;
$wp->add_query_var('latest_page');
}
add_filter('init', 'my_app_latest_add_query_var');
Then the widget I've got pulls out the posts as I want, but the pagination links don't show:
class MyApp_Widget_Recent_Posts extends WP_Widget {
public function __construct() {
$widget_ops = array('classname' => 'widget_recent_entries', 'description' => __( "Your site’s most recent Posts.") );
parent::__construct('recent-posts', __('MyApp Recent Posts'), $widget_ops);
$this->alt_option_name = 'widget_recent_entries';
add_action( 'save_post', array($this, 'flush_widget_cache') );
add_action( 'deleted_post', array($this, 'flush_widget_cache') );
add_action( 'switch_theme', array($this, 'flush_widget_cache') );
}
public function widget($args, $instance) {
$cache = array();
if ( ! $this->is_preview() ) {
$cache = wp_cache_get( 'widget_recent_posts', 'widget' );
}
if ( ! is_array( $cache ) ) {
$cache = array();
}
if ( ! isset( $args['widget_id'] ) ) {
$args['widget_id'] = $this->id;
}
if ( isset( $cache[ $args['widget_id'] ] ) ) {
echo $cache[ $args['widget_id'] ];
return;
}
ob_start();
$title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : __( 'MyApp Recent Posts' );
/** This filter is documented in wp-includes/default-widgets.php */
$title = apply_filters( 'widget_title', $title, $instance, $this->id_base );
$number = ( ! empty( $instance['number'] ) ) ? absint( $instance['number'] ) : 5;
if ( ! $number )
$number = 5;
$show_date = isset( $instance['show_date'] ) ? $instance['show_date'] : false;
$latest_page = ( get_query_var( 'latest_page' ) ) ? absint( get_query_var( 'latest_page' ) ) : 1;
$r = new WP_Query( apply_filters( 'widget_posts_args', array(
'posts_per_page' => $number,
'paged' => $latest_page,
'no_found_rows' => true,
'post_status' => 'publish',
'ignore_sticky_posts' => true,
'suppress_filters' => true
) ) );
if ($r->have_posts()) :
?>
<?php echo $args['before_widget']; ?>
<?php if ( $title ) {
echo $args['before_title'] . $title . $args['after_title'];
} ?>
<div class="latest-list">
<?php while ( $r->have_posts() ) : $r->the_post(); ?>
<?php get_template_part( 'content-block', get_post_format() ); ?>
<?php endwhile; ?>
</div>
<?php echo $args['after_widget']; ?>
<?php
echo '<div class="paginate-links">';
$args = array(
'base' => '/' . '%_%',
'format' => '?latest_page=%#%',
'current' => $latest_page,
'total' => $r->max_num_pages
);
echo paginate_links( $args );
echo '</div>'; ?>
<?php // This doesn't seem to work at all... ?>
<?php // echo get_next_posts_link( 'Load more', $r->max_num_pages ); ?>
<?php
// Reset the global $the_post as this query will have stomped on it
wp_reset_postdata();
endif;
if ( ! $this->is_preview() ) {
$cache[ $args['widget_id'] ] = ob_get_flush();
wp_cache_set( 'widget_recent_posts', $cache, 'widget' );
} else {
ob_end_flush();
}
}
}
I also created a function, which works for both i.e. displays posts and pagination links:
function my_app_recent_posts() {
global $post;
$latest_page = (get_query_var('latest_page')) ? get_query_var('latest_page') : 1;
$args = array(
'posts_per_page' => 1,
'order' => 'DESC',
'post_status' => 'publish',
'ignore_sticky_posts' => true,
'paged' => $latest_page
);
$rposts = new WP_Query($args);
if ( $rposts->have_posts() ) :
while ( $rposts->have_posts() ) : $rposts->the_post();
get_template_part( 'content-block', get_post_format() );
endwhile;
echo '<div class="pagination-links">';
$args = array(
'base' => '/' . '%_%',
'format' => '?latest_page=%#%',
'current' => $latest_page,
'total' => $rposts->max_num_pages
);
echo paginate_links( $args );
// This doesn't work as it just used the 'paged' query param
// echo get_next_posts_link( 'Load more', $rposts->max_num_pages );
wp_reset_postdata();
echo '</div>';
endif;
}
This doesn't seem right to me - there has got to be a way to just use the widget code surely?