This is an extention to your answer. Your pre_get_posts action has a few flaws
function add_custom_types_to_tax( $query ) {
if( is_category() || is_tag() && empty( $query->query_vars['suppress_filters'] ) ) {
// Get all your post types
$post_types = get_post_types();
$query->set( 'post_type', $post_types );
return $query;
}
}
add_filter( 'pre_get_posts', 'add_custom_types_to_tax' );
-
is_category()andis_tag()should be properties to$query -
There is not real benefit in checking whether
suppress_filtersis true or false. The main query is always set to to true unless set otherwise bypre_get_posts -
pre_get_postsis an action, not a filter -
Actions do not need to be returned.
-
pre_get_postsalters all instances ofWP_Query( the main query also usesWP_Query), front end and backend. You should always useis_main_query()to target the main query only, and also use!is_admin()to only target the front end ( this check is not necessary on the home page )
Your code should look something like this
function add_custom_types_to_tax( $query ) {
if( !is_admin() && $query->is_main_query() ) {
if ( $query->is_category() || $query->is_tag() ) {
// Get all your post types
$post_types = get_post_types();
$query->set( 'post_type', $post_types );
}
}
}
add_action( 'pre_get_posts', 'add_custom_types_to_tax' );
This should solve your issue without any further code needed
ADDITIONAL NOTES:
-
get_post_types()in the current state you are using it, it returns all registered post types including revisions and nav menu items. You would want to look atbuild_inparameter to exclude all build in types and just return custom post types. -
For non paginated custom queries, use
get_postsor add the following two parameters toWP_Query-
'suppress_filters' => trueThis will inhibit all filters from altering your custom query. -
‘
no_found_rows' => true'This will get the desired amount of posts and immediatly bail out. Default behavior ofWP_Queryis to look for all posts matching the query in order to count the posts for pagination purposes. This wastes time. Settingno_found_rowstotrue,WP_Queryskips this process. If it hit the desired amount of posts, it immediately stops execution of the query and returns the posts. This saves execution time, making the query faster.
-
(NOTE: get_posts() uses WP_Query with these two parameters already set accordingly. That is why get_posts cannot be sanely paged and why get_posts is not altered by filters)