Simple Posts Pagination in WordPress

If ypu have been following my WordPress Tutorials, I made two posts where I discussed how you can setup a pagination that loads the data from the server using AJAX. In this tutorial we are going to focus on creating a very simple pagination without AJAX and by just relying on PHP and WordPress functions. So let’s get started!

This simple pagination includes buttons for “Next”, “Prev”, “First”, and “Last”. You can also configure how many number bullets to show on screen.

Here’s the function that will setup the posts in a paginated view:

Comments are included so read on.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
function display_posts_pagination() {
   
    global $wpdb, $post;

    // Set default variables
    $pagination_content = '';
    $current_page_url = get_permalink( $post->ID );
    $page_number = isset( $_GET[ 'pageno' ] ) ? $_GET[ 'pageno' ] : 1;
   
    // Sanitize the received page  
    $page = sanitize_text_field( $page_number );
    $cur_page = $page;
    $page -= 1;
    // Set the number of results to display
    $per_page = 5;
    $previous_btn = true;
    $next_btn = true;
    $first_btn = true;
    $last_btn = true;
    $start = $page * $per_page;

    // Set the table where we will be querying data
    $table_name = $wpdb->prefix . 'posts';

    // Query the necessary posts
    $all_blog_posts = $wpdb->get_results( $wpdb->prepare( '
            SELECT * FROM '
. $table_name . ' WHERE post_type = "post" AND post_status = "publish" ORDER BY post_date DESC LIMIT %d, %d', $start, $per_page ) );

    // At the same time, count the number of queried posts
    $count = $wpdb->get_var( $wpdb->prepare( '
            SELECT COUNT(ID) FROM '
. $table_name . ' WHERE post_type = "post" AND post_status = "publish"', array() ) );

    /**
     * Use WP_Query:
     *
      $all_blog_posts = new WP_Query(
      array(
      'post_type'         => 'post',
      'post_status '      => 'publish',
      'orderby'           => 'post_date',
      'order'             => 'DESC',
      'posts_per_page'    => $per_page,
      'offset'            => $start
      )
      );

      $count = new WP_Query(
      array(
      'post_type'         => 'post',
      'post_status '      => 'publish',
      'posts_per_page'    => -1
      )
      );
     */

     
    // Loop into all the posts
    foreach ( $all_blog_posts as $key => $post ):

        // Set the desired output into a variable
        $pagination_content .= '
            <div class = "col-md-12">      
                <h2><a href="'
. get_permalink( $post->ID ) . '">' . $post->post_title . '</a></h2>
                <p>'
. $post->post_excerpt . '</p>
            </div>'
;

    endforeach;

    // Optional, wrap the output into a container
    $pagination_content = '<div class="cvf-universal-content">' . $pagination_content . '</div><br class = "clear" />';

    // This is where the magic happens
    $no_of_paginations = ceil( $count / $per_page );

    if ( $cur_page >= 7 ) {
        $start_loop = $cur_page - 3;
        if ( $no_of_paginations > $cur_page + 3 )
            $end_loop = $cur_page + 3;
        else if ( $cur_page <= $no_of_paginations && $cur_page > $no_of_paginations - 6 ) {
            $start_loop = $no_of_paginations - 6;
            $end_loop = $no_of_paginations;
        } else {
            $end_loop = $no_of_paginations;
        }
    } else {
        $start_loop = 1;
        if ( $no_of_paginations > 7 )
            $end_loop = 7;
        else
            $end_loop = $no_of_paginations;
    }

    // Pagination Buttons logic    
    $pagination_nav .= '
        <div class="pagination-container">
            <ul>'
;

    if ( $first_btn && $cur_page > 1 ) {
        $pagination_nav .= '<li class="active"><a href = "' . $current_page_url . '?pageno=1">First</a></li>';
    } else if ( $first_btn ) {
        $pagination_nav .= '<li class="inactive">First</li>';
    }

    if ( $previous_btn && $cur_page > 1 ) {
        $pre = $cur_page - 1;
        $pagination_nav .= '<li class="active"><a href = "' . $current_page_url . '?pageno=' . $pre . '">Previous</a></li>';
    } else if ( $previous_btn ) {
        $pagination_nav .= '<li class="inactive">Previous</li>';
    }
    for ( $i = $start_loop; $i <= $end_loop; $i ++  ) {

        if ( $cur_page == $i )
            $pagination_nav .= '<li class = "selected">' . $i . '</li>';
        else
            $pagination_nav .= '<li class="active"><a href = "' . $current_page_url . '?pageno=' . $i . '">' . $i . '</a></li>';
    }

    if ( $next_btn && $cur_page < $no_of_paginations ) {
        $nex = $cur_page + 1;
        $pagination_nav .= '<li class="active"><a href = "' . $current_page_url . '?pageno=' . $nex . '">Next</a></li>';
    } else if ( $next_btn ) {
        $pagination_nav .= '<li class="inactive">Next</li>';
    }

    if ( $last_btn && $cur_page < $no_of_paginations ) {
        $pagination_nav .= '<li class="active"><a href = "' . $current_page_url . '?pageno=' . $no_of_paginations . '">Last</a></li>';
    } else if ( $last_btn ) {
        $pagination_nav .= '<li class="inactive">Last</li>';
    }

    $pagination_nav = $pagination_nav . '
            </ul>
        </div>'
;
   
    $output = '
        <div>'
. $pagination_content . '</div>
        <div>'
. $pagination_nav . '</div>
    '
;
   
    return $output;
}

Simply copy the above code into your functions.php

Then in your page, simply call the function:

1
2
3
<div class = "content">
    <?php echo display_posts_pagination(); ?>
</div>

The function does not accept any parameters, but feel free to add some as you wish!

Styling

Here’s a ready made style for your navigation buttons:

1
2
3
4
5
6
7
.pagination-container  { margin-top: 15px; }
.pagination-container ul { margin: 0; padding: 0; }
.pagination-container ul li { display: inline; background: #FFF; color: black; }
.pagination-container ul li.active a:hover { background: #1E8CBE; color: white; text-decoration: none; }
.pagination-container ul li.inactive { background: #7E7E7E; }
.pagination-container ul li.selected { background: #1E8CBE; color: white; }
.pagination-container ul li a, .pagination-container ul li.inactive, .pagination-container ul li.selected { margin: 3px; padding: 4px 8px; }


Do you need help with a project? or have a new project in mind that you need help with?

Contact Me