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_filters
is true or false. The main query is always set to to true unless set otherwise bypre_get_posts
-
pre_get_posts
is an action, not a filter -
Actions do not need to be returned.
-
pre_get_posts
alters 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_in
parameter to exclude all build in types and just return custom post types. -
For non paginated custom queries, use
get_posts
or add the following two parameters toWP_Query
-
'suppress_filters' => true
This 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_Query
is to look for all posts matching the query in order to count the posts for pagination purposes. This wastes time. Settingno_found_rows
totrue
,WP_Query
skips 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)