Add Pagination in custom Blog page template

The solution:

The problem is $loop variable is not in global scope. So you need to add it to global in you blogslist.php file by adding global $loop; before $loop = new WP_Query($args); line.

More Efficient Way:

Alternatively, you can also pass $loop as an argument like this:

function wpbeginner_numeric_posts_nav($loop) {
// Codes here.. you also need to remove "global $loop" if you're using this method
}

Then Call it like this in blogslist.php file:

wpbeginner_numeric_posts_nav($loop);

Simple Way:

There’s also another simple way where you don’t need any custom function at all. In your blogslist.php file, after endwhile:

global $wp_query;

$wp_query_backup = $wp_query; // Take backup of the $wp_query
$wp_query = $loop; // Set your custom query as global $wp_query

the_posts_pagination(); // Calling the pagination, you can use it as you use in index or archive page, you may also use the_posts_navigation() here.

$wp_query = $wp_query_backup; // Restore the backup
wp_reset_query(); // Not really necessary but just to be sure

But this way is not recommended if you are developing themes for any repository, because it violates the guideline “Never modify $wp_query“.

Edit:

You must make your query listen to pagination, change your query args like this:

$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$query = new WP_Query( array(
    'posts_per_page' => 2,
    'post_type'     => 'blog', // I'm not sure if you're using custom post type or not. If it's default blog posts, then 'post_type' should be 'post' not blog. Or just don't add anything as post_type default is regular post
    'orderby'       => 'date',
    'order'         => 'DESC' 
    'paged' => $paged
) );

Also remove the code from your custom function to get pagination in page template as it’s a single page to WordPress:

if( is_singular() )
        return;