mcclosa
mcclosa

Reputation: 1455

wp_query->max_num_pages always returns 0 on custom post type

I am having an issue with my pagination that seems to stem from the fact that $wp_query->max_num_pages returns 0.

I believe that this is due to have 0 default wordpress posts.

So, I am using the WP Download Manager Pro plugin that creates a custom post type wpdmpro.

I have pages for each category, and using the loop, I loop through each post with a post-type of wpdmpro.

<?php
    $paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
    $args = array(
        'orderby'           => 'date',
        'order'             => 'DESC',
        'post_status'       => 'publish',
        'posts_per_page'    => 2,
        'paged'             => $paged,
        'post_type' => 'wpdmpro', 
        'wpdmcategory' => $category->category_nicename,
        'tag' => $cat_tag
    );
    query_posts($args)
?>
<?php if (have_posts()) : ?>
   /* content goes here */
<?php endif; ?>
<?php else : ?>

    <div class="row">
        <h2 class="center">Not Found</h2>
        <p class="center">Sorry, but you are looking for something that isn't here.</p>
        <?php get_search_form(); ?>
    </div>

<?php endif; ?>
echo $wp_query->max_num_pages /* returns 0 */
echo $wp_query->found_posts   /* returns 0 */

Although, I actually have 11 posts in the wpdmpro post_type. So why do the echos not doing the following?

echo $wp_query->max_num_pages /* Should return 2 because I have 11 posts with 10 per page */
echo $wp_query->found_posts   /* Shoudl return 11 because I have 11 posts */

Tried the following to see if this would work

  add_action( 'pre_get_posts', 'action_pre_get_posts' );
  function action_pre_get_posts( $q ) 
  {
    $q->set('max_num_pages', 20);
  }

But when navigating to page/2/ I still get a 404 page.

The url I am hitting is /category-name/page/2 which returns a 404.

There must be a solution to this?

How do I make my site ignore the default WordPress post types and use what I actually define, the wpdmpro post types?

Edit: I have tried to use the WP_Query class too, but still hitting a 404 page when navigating to /page/2

Just a few things to add in case they are somehow linked.

In my permalinks settings, I have a custom structure of

/%category%/%postname%/

and my default category base is .

In my WP Download Manager Settings, my WPDM Category URL Base is .

I also have these 2 filter functions, that were copied from answers on here, and I am quite new to Wordpress so I am not sure of the potential repercussions of using these are?

add_filter('category_rewrite_rules', 'vipx_filter_category_rewrite_rules');
add_filter('user_trailingslashit', 'remove_category', 100, 2);
function vipx_filter_category_rewrite_rules($rules) {
    $categories = get_categories(array('hide_empty' => false));

    if (is_array($categories) && !empty($categories)) {
        $slugs = array();
        foreach($categories as $category) {
            if (is_object($category) && !is_wp_error($category)) {
                if (0 == $category - > category_parent) {
                    $slugs[] = $category - > slug;
                } else {
                    $slugs[] = trim(get_category_parents($category - > term_id, false, '/', true), '/');
                }
            }
        }

        if (!empty($slugs)) {
            $rules = array();

            foreach($slugs as $slug) {
                $rules['('.$slug.
                    ')/feed/(feed|rdf|rss|rss2|atom)?/?$'] = 'index.php?category_name=$matches[1]&feed=$matches[2]';
                $rules['('.$slug.
                    ')/(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?category_name=$matches[1]&feed=$matches[2]';
                $rules['('.$slug.
                    ')(/page/(\d+)/?)?$'] = 'index.php?category_name=$matches[1]&paged=$matches[3]';
            }
        }
    }
    return $rules;
}

function remove_category($string, $type) {
    if ($type != 'single' && $type == 'category' && (strpos($string, 'category') !== false)) {
        $url_without_category = str_replace("/wpdmcategory/", "/", $string);
        return trailingslashit($url_without_category);
    }
    return $string;
}

I also ensured that none of the posts slugs were conflicting with the category name.

Upvotes: 2

Views: 15522

Answers (4)

Matt
Matt

Reputation: 34

This function let you find the number of custom posts you have :

$num_posts = wp_count_posts('your_custom_post_type')->publish;

(cf. documentation )

So, you can obtain the max_num_pages value through a simple operation between this and the posts_per_page value :

$max_num_pages = $num_posts / $your_posts_per_page;
if ($num_posts % $your_posts_per_page > 0) $max_num_pages++;

Upvotes: 1

squarecandy
squarecandy

Reputation: 5107

Also... make sure you don't have no_found_rows set to true in your WP_Query args.

Upvotes: 4

mcclosa
mcclosa

Reputation: 1455

Just in case anyone ever stumbles across this, I found the solution.

First step was to create an archive.php page

In there I would access the loop.

The in functions.php

I have a category rewrite filter to update the category rewrite rules to use the following example url index.php?wpdmcategory=category-name&paged=2 when I hit /category-name/page/2

Previously, it was using the following example url, index.php?category_name=category-name&paged=2 so it was actually using the default post type for the category paging.

add_filter( 'category_rewrite_rules', 'vipx_filter_category_rewrite_rules' );`

function vipx_filter_category_rewrite_rules($rules) {
    $categories = get_terms('wpdmcategory', array("hide_empty" => false));

    if (is_array($categories) && !empty($categories)) {
        $slugs = array();
        foreach($categories as $category) {
            if (is_object($category) && !is_wp_error($category)) {
                if (0 == $category - > category_parent) {
                    $slugs[] = $category - > slug;
                } else {
                    $slugs[] = trim(get_category_parents($category - > term_id, false, '/', true), '/');
                }
            }
        }

        if (!empty($slugs)) {
            $rules = array();

            foreach($slugs as $slug) {
                $rules['('.$slug.
                    ')/feed/(feed|rdf|rss|rss2|atom)?/?$'] = 'index.php?wpdmcategory=$matches[1]&feed=$matches[2]';
                $rules['('.$slug.
                    ')/(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?wpdmcategory=$matches[1]&feed=$matches[2]';
                $rules['('.$slug.
                    ')(/page/(\d+)/?)?$'] = 'index.php?wpdmcategory=$matches[1]&paged=$matches[3]';
            }
        }
    }
    return $rules;
}

Upvotes: 0

Shoelaced
Shoelaced

Reputation: 881

You should really avoid query_posts() when you can, opting for the WP_Query class instead. Something like this:

<?php
// Args
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$args = array(
    'orderby'           => 'date',
    'order'             => 'DESC',
    'post_status'       => 'publish',
    'posts_per_page'    => 2,
    'paged'             => $paged,
    'post_type'         => 'wpdmpro', 
    'wpdmcategory'      => $category->category_nicename,
    'tag'               => $cat_tag
);

// Query
$wpdmpro_query = new WP_Query( $args );

// The Loop
if( $wpdmpro_query->have_posts() ) : while( $wpdmpro_query->have_posts() ) : $wpdmpro_query->the_post();
?>
    <!-- Do stuff -->

<?php endwhile; ?>

    <!-- Do stuff if there are no posts -->

endif; wp_reset_postdata(); ?>

And then to test max_num_pages you'd use the query:

echo $wpdmpro_query->max_num_pages

Hope this helps!

Upvotes: 1

Related Questions