1

I have a category template with a custom post type that looks like:

<?php
    $category = get_query_var('cat');
    $paged = (get_query_var("page")) ? get_query_var("paged") : 1;
    $args = array(
        'cat' => $category,
        'paged' => $paged,
        'post_mime_type' => 'image',
        'posts_per_page' => 9,
        'post_status' => 'inherit',
        'post_type' => 'attachment'
    );
    query_posts($args);
    $count = $wp_query->found_posts; 
?>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
    <a href="<?php the_permalink(); ?>"><?php echo wp_get_attachment_image($image->ID, "medium"); ?></a>
    <h5><?php the_title(); ?></h5>
    <?php
        $attachment = get_post(get_post_thumbnail_id()); // Get post by ID
        echo '<p>'.$attachment->post_content.'</p>'
    ?>
<?php endwhile; endif; ?>
    <ul class="pagi">
        <li><?php posts_nav_link(' | ','< Previous','Next >'); ?></li>
        <li><?php echo "(Page: ". $paged . " of " . $wp_query->max_num_pages .")"; ?></li>
    </ul>
<?php wp_reset_query(); ?>

Everything is working except the paging...when I view page 2 the url looks like: http://joshrodg.com/ourpictureshare/category/pictures/unknown/page/2/, which is a 404.

I'm not sure what the URL is supposed to look like, but I think the post type in my query is causing the issue.

Could someone point me in the right direction?

Thanks,
Josh

1
  • 1
    A 404 is based on the results of the main query, use pre_get_posts to alter the main query instead of creating a new query in the template.
    – Milo
    Commented Aug 2, 2017 at 2:43

1 Answer 1

0

I found a solution!

I was able to find a function that modified the query on the category page (https://wordpress.org/support/topic/custom-types-category-pagination-404/#post-1913902 - on the first page toward the bottom, written by: Mark / t31os).

Add this to functions.php:

add_action( 'parse_query','changept' );
function changept() {
    $category = get_query_var('cat');
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    if (is_category() && !is_admin())
        set_query_var( 'cat', $category );
        set_query_var( 'paged', $paged );
        set_query_var( 'posts_per_page', 9 );
        set_query_var( 'post_status', 'inherit' );
        set_query_var( 'post_type', 'attachment' );
    return;
}

This is what category.php looks like now:

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
    <a href="<?php the_permalink(); ?>"><?php echo wp_get_attachment_image($image->ID, "medium"); ?></a>
    <h5><?php the_title(); ?></h5>
    <?php
        $attachment = get_post(get_post_thumbnail_id()); // Get post by ID
        echo '<p>'.$attachment->post_content.'</p>'
    ?>
<?php endwhile; endif; ?>
    <ul class="pagi">
        <li><?php posts_nav_link(' | ','< Previous','Next >'); ?></li>
        <li><?php echo "(Page: ". $paged . " of " . $wp_query->max_num_pages .")"; ?></li>
    </ul>

UPDATE:

I ran into a problem with my solution...it was executing on all the pages. All pages except the category page were returning a 404, So I needed to run the code only on the category page to fix the issue.

Here is the updated code functions.php:

$url = $_SERVER['REQUEST_URI'];
if (strpos($url,'category') !== false) {
    add_action( 'parse_query','changept' );
    function changept() {
        $category = get_query_var('cat');
        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
        if (is_main_query()) {
            set_query_var( 'cat', $category );
            set_query_var( 'paged', $paged );
            set_query_var( 'posts_per_page', 9 );
            set_query_var( 'post_status', 'inherit' );
            set_query_var( 'post_type', 'attachment' );
        }
        return;
    }
}

Basically, this checks to see if the word "category" is part of the url, and because I am only using this on my category.php page, this will work without affecting any other page. There is probably a better solution out there, but this works for my project. Also, another if was added to target the main query: is_main_query()...this way if you have other queries on the page, they will still function normally.

I'm sure you can do something similar with pre_get_posts, which is Milo's suggestion, but I just couldn't figure out how to use that function with my template.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.