Skip to main content
deleted 56 characters in body
Source Link
webtoure
  • 1.5k
  • 1
  • 8
  • 12

If you don't mind the cost of calling COUNT to first get the total number of posts (you have a dynamic first page in terms of numbers of posts so it doesn't work with a simple offset) here is something that I've wrote (it's late and I am tired so it might have some bugs / might not be the right solution):

// This code can be placed in the 'functions.php' file.
function wt_post_clauses_hookwt_posts_clauses_hook( $clauses, $query ) {
    if ( $query->is_main_query() && $query->is_home() ) {
        global $wpdb;

        extract( $clauses );

        if ( ! empty( $groupby ) ) $groupby = 'GROUP BY ' . $groupby;

        $sql = "SELECT COUNT(ID) FROM $wpdb->posts $join WHERE 1=1 $where $groupby";
        $no_posts = $wpdb->get_var( $sql );
 
        $posts_per_page = get_option( 'posts_per_page' );
        $extra = $no_posts % $posts_per_page;
        $paged = absint( $query->get( 'paged' ) );
        
        if ( ! $paged ) $paged = 1;

        $from = ( $paged - 1 ) * $posts_per_page;
        $to = $posts_per_page;

        if ( $paged < 2$extra ) {
            if ( $extra$paged < 2 ) {
                $from = 0;
                $to = $extra;
            }
        } else {
            if ( $extra ) {
                $from = $posts_per_page * ( $paged - 2 ) + $extra;
            }
        }           

        $clauses['limits'] = "LIMIT {$from}, {$to}";
    }

    return $clauses;
 
}
add_filter( 'posts_clauses_request', 'wt_post_clauses_hook''wt_posts_clauses_hook', 99, 2 );

You can probably implement a caching mechanism if you don't want to run this on every listing page call by reading the found_posts property. If it doesn't correspond to the cache entry you simply delete the cache. Of course, you first have to modify this function above to initially try and read the $no_posts value from cache. If there is none then run the $sql query and create the cache with the corresponding $no_posts value.

If you don't mind the cost of calling COUNT to first get the total number of posts (you have a dynamic first page in terms of numbers of posts so it doesn't work with a simple offset) here is something that I've wrote (it's late and I am tired so it might have some bugs / might not be the right solution):

// This code can be placed in the 'functions.php' file.
function wt_post_clauses_hook( $clauses, $query ) {
    if ( $query->is_main_query() && $query->is_home() ) {
        global $wpdb;

        extract( $clauses );

        if ( ! empty( $groupby ) ) $groupby = 'GROUP BY ' . $groupby;

        $sql = "SELECT COUNT(ID) FROM $wpdb->posts $join WHERE 1=1 $where $groupby";
        $no_posts = $wpdb->get_var( $sql );
 
        $posts_per_page = get_option( 'posts_per_page' );
        $extra = $no_posts % $posts_per_page;
        $paged = absint( $query->get( 'paged' ) );
        
        if ( ! $paged ) $paged = 1;

        $from = ( $paged - 1 ) * $posts_per_page;
        $to = $posts_per_page;

        if ( $paged < 2 ) {
            if ( $extra ) {
                $from = 0;
                $to = $extra;
            }
        } else {
            if ( $extra ) {
                $from = $posts_per_page * ( $paged - 2 ) + $extra;
            }
        }

        $clauses['limits'] = "LIMIT {$from}, {$to}";
    }

    return $clauses;
 
}
add_filter( 'posts_clauses_request', 'wt_post_clauses_hook', 99, 2 );

You can probably implement a caching mechanism if you don't want to run this on every listing page call by reading the found_posts property. If it doesn't correspond to the cache entry you simply delete the cache. Of course, you first have to modify this function above to initially try and read the $no_posts value from cache. If there is none then run the $sql query and create the cache with the corresponding $no_posts value.

If you don't mind the cost of calling COUNT to first get the total number of posts (you have a dynamic first page in terms of numbers of posts so it doesn't work with a simple offset) here is something that I've wrote (it's late and I am tired so it might have some bugs / might not be the right solution):

// This code can be placed in the 'functions.php' file.
function wt_posts_clauses_hook( $clauses, $query ) {
    if ( $query->is_main_query() && $query->is_home() ) {
        global $wpdb;

        extract( $clauses );

        if ( ! empty( $groupby ) ) $groupby = 'GROUP BY ' . $groupby;

        $sql = "SELECT COUNT(ID) FROM $wpdb->posts $join WHERE 1=1 $where $groupby";
        $no_posts = $wpdb->get_var( $sql );
        $posts_per_page = get_option( 'posts_per_page' );
        $extra = $no_posts % $posts_per_page;
        $paged = absint( $query->get( 'paged' ) );
        
        if ( ! $paged ) $paged = 1;

        $from = ( $paged - 1 ) * $posts_per_page;
        $to = $posts_per_page;

        if ( $extra ) {
            if ( $paged < 2 ) {
                $from = 0;
                $to = $extra;
            } else {
                $from = $posts_per_page * ( $paged - 2 ) + $extra;
            }
        }           

        $clauses['limits'] = "LIMIT {$from}, {$to}";
    }

    return $clauses;
}
add_filter( 'posts_clauses_request', 'wt_posts_clauses_hook', 99, 2 );

You can probably implement a caching mechanism if you don't want to run this on every listing page call by reading the found_posts property. If it doesn't correspond to the cache entry you simply delete the cache. Of course, you first have to modify this function above to initially try and read the $no_posts value from cache. If there is none then run the $sql query and create the cache with the corresponding $no_posts value.

added 40 characters in body
Source Link
webtoure
  • 1.5k
  • 1
  • 8
  • 12

If you don't mind the cost of calling COUNT to first get the total number of posts (you have a dynamic first page in terms of numbers of posts so it doesn't work with a simple offset) here is something that I've wrote (it's late and I am tired so it might have some bugs / might not be the right solution):

// This code can be placed in the 'functions.php' file.
function wt_post_clauses_hook( $clauses, $query ) {
    if ( $query->is_main_query() && $query->is_home() ) {
        global $wpdb;

        extract( $clauses );

        if ( ! empty( $groupby ) ) $groupby = 'GROUP BY ' . $groupby;

        $sql = "SELECT COUNT(ID) FROM $wpdb->posts $join WHERE 1=1 $where $groupby";
        $no_posts = $wpdb->get_var( $sql );

        $posts_per_page = get_option( 'posts_per_page' );
        $extra = $no_posts % $posts_per_page;
        $paged = absint( $query->get( 'paged' ) );
        
        if ( ! $paged ) $paged = 1;

        $from = ( $paged - 1 ) * $posts_per_page;
        $to = $posts_per_page;

        if ( ! $paged < 2 ) {
            if ( $extra ) {
                $from = 0;
                $to = $extra;
            }
        } else {
            if ( $extra ) {
                $from = $posts_per_page * ( $paged - 2 ) + $extra;
            }
        }

        $clauses['limits'] = "LIMIT {$from}, {$to}";
    }

    return $clauses;

}
add_filter( 'posts_clauses_request', 'wt_post_clauses_hook', 99, 2 );

You can probably implement a caching mechanism if you don't want to run this on every listing page call by reading the found_posts property. If it doesn't correspond to the cache entry you simply delete the cache. Of course, you first have to modify this function above to initially try and read the $no_posts value from cache. If there is none then run the $sql query and create the cache with the corresponding $no_posts value.

If you don't mind the cost of calling COUNT to first get the total number of posts (you have a dynamic first page in terms of numbers of posts so it doesn't work with a simple offset) here is something that I've wrote (it's late and I am tired so it might have some bugs / might not be the right solution):

// This code can be placed in the 'functions.php' file.
function wt_post_clauses_hook( $clauses, $query ) {
    if ( $query->is_main_query() && $query->is_home()) {
        global $wpdb;

        extract( $clauses );

        if ( ! empty( $groupby ) ) $groupby = 'GROUP BY ' . $groupby;

        $sql = "SELECT COUNT(ID) FROM $wpdb->posts $join WHERE 1=1 $where $groupby";
        $no_posts = $wpdb->get_var( $sql );

        $posts_per_page = get_option( 'posts_per_page' );
        $extra = $no_posts % $posts_per_page;
        $paged = absint( $query->get( 'paged' ) );

        $from = ( $paged - 1 ) * $posts_per_page;
        $to = $posts_per_page;

        if ( ! $paged ) {
            if ( $extra ) {
                $from = 0;
                $to = $extra;
            }
        } else {
            if ( $extra ) {
                $from = $posts_per_page * ( $paged - 2 ) + $extra;
            }
        }

        $clauses['limits'] = "LIMIT {$from}, {$to}";
    }

    return $clauses;

}
add_filter( 'posts_clauses_request', 'wt_post_clauses_hook', 99, 2 );

You can probably implement a caching mechanism if you don't want to run this on every listing page call by reading the found_posts property. If it doesn't correspond to the cache entry you simply delete the cache. Of course, you first have to modify this function above to initially try and read the $no_posts value from cache. If there is none then run the $sql query and create the cache with the corresponding $no_posts value.

If you don't mind the cost of calling COUNT to first get the total number of posts (you have a dynamic first page in terms of numbers of posts so it doesn't work with a simple offset) here is something that I've wrote (it's late and I am tired so it might have some bugs / might not be the right solution):

// This code can be placed in the 'functions.php' file.
function wt_post_clauses_hook( $clauses, $query ) {
    if ( $query->is_main_query() && $query->is_home() ) {
        global $wpdb;

        extract( $clauses );

        if ( ! empty( $groupby ) ) $groupby = 'GROUP BY ' . $groupby;

        $sql = "SELECT COUNT(ID) FROM $wpdb->posts $join WHERE 1=1 $where $groupby";
        $no_posts = $wpdb->get_var( $sql );

        $posts_per_page = get_option( 'posts_per_page' );
        $extra = $no_posts % $posts_per_page;
        $paged = absint( $query->get( 'paged' ) );
        
        if ( ! $paged ) $paged = 1;

        $from = ( $paged - 1 ) * $posts_per_page;
        $to = $posts_per_page;

        if ( $paged < 2 ) {
            if ( $extra ) {
                $from = 0;
                $to = $extra;
            }
        } else {
            if ( $extra ) {
                $from = $posts_per_page * ( $paged - 2 ) + $extra;
            }
        }

        $clauses['limits'] = "LIMIT {$from}, {$to}";
    }

    return $clauses;

}
add_filter( 'posts_clauses_request', 'wt_post_clauses_hook', 99, 2 );

You can probably implement a caching mechanism if you don't want to run this on every listing page call by reading the found_posts property. If it doesn't correspond to the cache entry you simply delete the cache. Of course, you first have to modify this function above to initially try and read the $no_posts value from cache. If there is none then run the $sql query and create the cache with the corresponding $no_posts value.

added 205 characters in body
Source Link
webtoure
  • 1.5k
  • 1
  • 8
  • 12

If you don't mind the cost of calling COUNT to first get the total number of posts (you have a dynamic first page in terms of numbers of posts so it doesn't work with a simple offset) here is something that I've wrote (it's late and I am tired so it might have some bugs / might not be the right solution):

// This code can be placed in the 'functions.php' file.
add_filter( 'posts_clauses_request', function wt_post_clauses_hook( $clauses, $query ) {
    if ( $query->is_main_query() && $query->is_home()) {
        global $wpdb;

        extract( $clauses );

        if ( ! empty( $groupby ) ) $groupby = 'GROUP BY ' . $groupby;

        $sql = "SELECT COUNT(ID) FROM $wpdb->posts $join WHERE 1=1 $where $groupby";
        $no_posts = $wpdb->get_var( $sql );

        $posts_per_page = get_option( 'posts_per_page' );
        $extra = $no_posts % $posts_per_page;
        $paged = absint( $query->get( 'paged' ) );
        
        $from = ( $paged - 1 ) * $posts_per_page;
        $to = $posts_per_page;

        if ( ! $paged ) {
            if ( $extra ) {
                $from = 0;
                $to = $extra;
            }
        } else {
            if ( $extra ) {
                $from = $posts_per_page * ( $paged - 2 ) + $extra;
            }
        }

        $clauses['limits'] = "LIMIT {$from}, {$to}";
    }

    return $clauses;

}
add_filter( 'posts_clauses_request', 'wt_post_clauses_hook', 99, 2 );

You can probably implement a caching mechanism if you don't want to run this on every listing page call by reading the found_posts property. If it doesn't correspond to the cache entry you simply delete the cache. Of course, you first have to modify this function above to initially try and read the $no_posts value from cache. If there is none then run the $sql query and create the cache with the corresponding $no_posts value.

If you don't mind the cost of calling COUNT to first get the total number of posts (you have a dynamic first page in terms of numbers of posts so it doesn't work with a simple offset) here is something that I've wrote (it's late and I am tired so it might have some bugs / might not be the right solution):

// This code can be placed in the 'functions.php' file.
add_filter( 'posts_clauses_request', function( $clauses, $query ) {
    if ( $query->is_main_query() && $query->is_home()) {
        global $wpdb;

        extract( $clauses );

        if ( ! empty( $groupby ) ) $groupby = 'GROUP BY ' . $groupby;

        $sql = "SELECT COUNT(ID) FROM $wpdb->posts $join WHERE 1=1 $where $groupby";
        $no_posts = $wpdb->get_var( $sql );

        $posts_per_page = get_option( 'posts_per_page' );
        $extra = $no_posts % $posts_per_page;
        $paged = absint( $query->get( 'paged' ) );
        
        $from = ( $paged - 1 ) * $posts_per_page;
        $to = $posts_per_page;

        if ( ! $paged ) {
            if ( $extra ) {
                $from = 0;
                $to = $extra;
            }
        } else {
            if ( $extra ) {
                $from = $posts_per_page * ( $paged - 2 ) + $extra;
            }
        }

        $clauses['limits'] = "LIMIT {$from}, {$to}";
    }

    return $clauses;

}, 99, 2 );

You can probably implement a caching mechanism if you don't want to run this on every listing page call by reading the found_posts property. If it doesn't correspond to the cache entry you simply delete the cache. Of course, you first have to modify this function above to initially try and read the $no_posts value from cache. If there is none then run the $sql query and create the cache with the corresponding $no_posts value.

If you don't mind the cost of calling COUNT to first get the total number of posts (you have a dynamic first page in terms of numbers of posts so it doesn't work with a simple offset) here is something that I've wrote (it's late and I am tired so it might have some bugs / might not be the right solution):

// This code can be placed in the 'functions.php' file.
function wt_post_clauses_hook( $clauses, $query ) {
    if ( $query->is_main_query() && $query->is_home()) {
        global $wpdb;

        extract( $clauses );

        if ( ! empty( $groupby ) ) $groupby = 'GROUP BY ' . $groupby;

        $sql = "SELECT COUNT(ID) FROM $wpdb->posts $join WHERE 1=1 $where $groupby";
        $no_posts = $wpdb->get_var( $sql );

        $posts_per_page = get_option( 'posts_per_page' );
        $extra = $no_posts % $posts_per_page;
        $paged = absint( $query->get( 'paged' ) );

        $from = ( $paged - 1 ) * $posts_per_page;
        $to = $posts_per_page;

        if ( ! $paged ) {
            if ( $extra ) {
                $from = 0;
                $to = $extra;
            }
        } else {
            if ( $extra ) {
                $from = $posts_per_page * ( $paged - 2 ) + $extra;
            }
        }

        $clauses['limits'] = "LIMIT {$from}, {$to}";
    }

    return $clauses;

}
add_filter( 'posts_clauses_request', 'wt_post_clauses_hook', 99, 2 );

You can probably implement a caching mechanism if you don't want to run this on every listing page call by reading the found_posts property. If it doesn't correspond to the cache entry you simply delete the cache. Of course, you first have to modify this function above to initially try and read the $no_posts value from cache. If there is none then run the $sql query and create the cache with the corresponding $no_posts value.

added 81 characters in body
Source Link
webtoure
  • 1.5k
  • 1
  • 8
  • 12
Loading
Source Link
webtoure
  • 1.5k
  • 1
  • 8
  • 12
Loading