Custom taxonomy and custom post type with custom p

2019-01-28 18:01发布

问题:

My pagination is throwing a 404 error when the posts from General -> Reading are smaller than my custom number of posts on my custom taxonomy cities (custom post type city). From what I saw on SO this issue can be fixed usually by using a filter of pre_get_posts, but don't know how to apply it on my case. I want to mention that in the taxonomy-cities.php I am getting posts of a category of a custom taxonomy of a custom post type.

taxonomy-cities.php

$cat_ID = get_query_var('cities');
$custom_id = get_term_by('slug', $cat_ID, 'cities');
add_filter('posts_orderby', 'edit_posts_orderby');
function edit_posts_orderby($orderby_statement) {
    global $aPostsIDs;
    $orderby_statement = 'FIELD(ID, '.implode(',',$_SESSION['saved_city_ids']).')';
    return $orderby_statement;
}
$offset     = ($paged - 1) * $num_city_guides_post; 
$args['post_type'] = 'city'; 
$args['posts_per_page'] = $num_city_guides_post; // 5
$args['orderby'] = $orderby; // rand
$args['order'] = $order; // DESC
$args['paged'] = $paged; // 1
$args['tax_query'] = array(
                        array(
                               'taxonomy' => 'cities',
                               'field' => 'id',
                               'terms' =>  array($custom_id->term_id) // 3742
                             )
                    );
}
$wp_query = new WP_Query($args);
if ( $wp_query->have_posts() ) : 
  while ( $wp_query->have_posts() ) : $wp_query->the_post();
  // some code here
  endwhile; 
else: echo 'No Posts';
endif; 
wp_reset_postdata();

For archive-city.php I am using this filter in the functions.php and it works fine, but it doesn't get applied to the taxonomy-cities.php so I get 404:

function portfolio_posts_per_page_city( $query ) {
        if (array_key_exists('post_type', $query->query_vars)) {
        if ( $query->query_vars['post_type'] == 'city' ) 
        $num_city_guides_post = get_option('num_city_post');
        if( empty( $num_city_guides_post ) )
        $num_city_guides_post = 9;

        $query->query_vars['posts_per_page'] = $num_city_guides_post;
        return $query;
    }
}
if ( !is_admin() ) add_filter( 'pre_get_posts', 'portfolio_posts_per_page_city' );

回答1:

Maybe u can solve this without filters. It`s work for pagination my custom posts types

$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$args = array( 'post_type' =>'cities', 'posts_per_page' => 0, 'paged' => $paged );
$query = query_posts( $args );
if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
//Do wordpress Loop
<?php endwhile; else:  include( get_404_template() ); ?>
<?php endif; wp_reset_postdata(); ?>


回答2:

I had the same problem with my custom post taxonomies pagination. Older posts page was coming with a 404 page not found. This issue is related to WP taxonomy slug so you have to rewrite rules for your custom post type taxonomies like this below:

function generate_taxonomy_rewrite_rules( $wp_rewrite ) {

    $rules = array();

    $post_types = get_post_types( array( 'public' => true, '_builtin' => false ), 'objects' );
    $taxonomies = get_taxonomies( array( 'public' => true, '_builtin' => false ), 'objects' );

    foreach ( $post_types as $post_type ) {
        $post_type_name = $post_type->name;
        $post_type_slug = $post_type->rewrite['slug'];

        foreach ( $taxonomies as $taxonomy ) {
            if ( $taxonomy->object_type[0] == $post_type_name ) {
                $terms = get_categories( array( 'type' => $post_type_name, 'taxonomy' => $taxonomy->name, 'hide_empty' => 0 ) );
                foreach ( $terms as $term ) {
                    $rules[$post_type_slug . '/' . $term->slug . '/?$'] = 'index.php?' . $term->taxonomy . '=' . $term->slug;
                    $rules[$post_type_slug . '/' . $term->slug . '/page/?([0-9]{1,})/?$'] = 'index.php?' . $term->taxonomy . '=' . $term->slug . '&paged=' . $wp_rewrite->preg_index( 1 );
                }
            }
        }
    }

    $wp_rewrite->rules = $rules + $wp_rewrite->rules;

}

add_action('generate_rewrite_rules', 'generate_taxonomy_rewrite_rules');

This should work for all custom post type taxonomies and if you want to be more specific then you can try updating these two variables like this:

$post_types = get_post_types( array( 'name' => 'city', 'public' => true, '_builtin' => false ), 'objects' );

$taxonomies = get_taxonomies( array( 'name' => 'cities', 'public' => true, '_builtin' => false ), 'objects' );

Finally, just use your default query loop without passing any arguments. Pages will be generated based on General -> Reading.



回答3:

This is an old question however i recently had the same issue. The following Snippet is in fact the contents of my taxonomy-template.php using the standard WP_Query, example here.

How to properly paginate custom post type taxonomy

The Query

  • Firstly because it's a taxonomy template, the first line declares $term allowing me to access the term array and therefore the taxonomy id, name url etc.

  • Secondly i'm setting the term id as a variable to be used in the tax_query parameter. This is used to query my custom post type videos and then get the taxonomy (category) for the loop, stored in $term_id.

The Fix

  • Because i'm looping through the posts and limiting the results, we effectively need to search for our remaining posts while excluding the previous results and results thereafter. What this means is quite simple:

You must make your custom post types searchable in order for pagination to work:

Important:

'exclude_from_search' => false,


Example taxonomy-template.php

<?php $term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); ?>

<?php
$term_id = $term->term_id;
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$args = array(
  'post_type'       => 'videos',
  'posts_per_page'  => 4,
  'paged'           => $paged,
  'tax_query'       => array(
    array(
      'taxonomy' => $term->taxonomy,
      'field' => 'term_id',
      'terms' => $term_id
    )
  )
);
$the_query = new WP_Query( $args );
?>

<?php if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
  <!-- Loop -->
<?php endwhile; ?>
<?php if ($the_query->max_num_pages > 1) :  ?>
<?php endif; ?>
<?php else: ?>
  <!-- Nothing Found -->
<?php endif; ?>