EDIT
From your comments, front-page.php
is only used when a page is set as a static front page. Normal home pages, ie, when Front page displays is set to Your latest posts, index.php
is used.
All archive pages and the front page uses paged
and not page
, so you would need to set get_query_var( 'page' )
to get_query_var( 'paged' )
.
Any ways, you should not be using a custom query on your home page, you should be using pre_get_posts
to alter the main query to your needs
add_action( 'pre_get_posts', function ( $q )
{
if ( $q->is_home()
&& $q->is_main_query()
) {
$q->set( 'category_name', 'featured' );
$q->set( 'posts_per_page', 4 );
}
});
Your pagination links should then be
next_posts_link( 'Next' );
previous_posts_link( 'Previous' );
Your loop in index.php
should look like this
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
// Your markup and template tags
}
}
If you really need to use front-page.php
as a normal home page and not a static front page, then you need to do the following
-
Change your loop to what I have suggested above with the pagination links
-
Use
pre_get_posts
as suggested as above to change the main query according to your need -
Use the
home_template
filter to usefront-page.php
as your homepage template
You can try the following
add_filter( 'home_template', function ( $template )
{
$locate_template = locate_template( 'front-page.php' );
if ( !$locate_template )
return $template;
return $locate_template;
});
ORIGINAL ANSWER
The functions next_posts_link()
and previous_posts_link()
don’t work on static front pages out of the box. The issue is, pagination uses get_query_var( 'paged' )
which is saved in the $paged
global. Because static front pages uses get_query_var( 'page' )
and not get_query_var( 'paged' )
, your links will never paginate past page 1.
We can trick next_posts_link()
and previous_posts_link()
to think they are used on an archive page by setting the $paged
global to get_query_var( 'page' )
.
You can try the following
$paged = get_query_var( 'page', 1 );
$args = [];
$args['post_type'] = 'post';
$args['post_status'] = 'publish';
$args['category_name'] = 'featured';
$args['posts_per_page'] = 4;
$args['paged'] = $paged;
$the_query = new WP_Query($args);
if ($the_query->have_posts()) {
while ($the_query->have_posts()) {
$the_query->the_post() ;
the_title();
} // End of: while ($the_query->have_posts())
next_posts_link('Next', $the_query->max_num_pages );
previous_posts_link('Previous');
wp_reset_postdata(); // VERY VERY IMPORTANT
} // End of: if ($the_query->have_posts())
EDIT
You can also make use of the following on your static front page
$query = new PreGetPostsForPages(
251, // Page ID we will target, your static front page ID
'content', //Template part which will be used to display posts, name should be without .php extension
false, // Should get_template_part support post formats
true, // Should the page object be excluded from the loop
[ // Array of valid arguments that will be passed to WP_Query/pre_get_posts
'post_type' => 'post',
'category_name' => 'featured',
'posts_per_page' => 4
]
);
$query->init();
where the PreGetPostsForPages
class is supported by my answer here
add_action( 'pregetgostsforgages_after_loop_pagination', function ()
{
$paged = get_query_var( 'page', 1 );
next_posts_link( 'Next' );
previous_posts_link( 'Previous' );
});