Rather than using pre_get_posts
hook, you could try a better approach which will work perfectly with parse_request
hook. The code –
add_action( 'parse_request', 'my_cpt_parse_request', 11, 2 );
function my_cpt_parse_request( $wp )
{
if( isset($wp->request) && !is_admin() )
{
$requests = explode("https://wordpress.stackexchange.com/", $wp->request);
$request_amount = count($requests);
$post_name = array_shift( $requests );
// if an attachment has been queried under this or another post type, skip checking
if( $request_amount > 1 && !in_array( $requests['0'], array('feed', 'page') ) )
return;
global $wpdb;
$post = $wpdb->get_row( $wpdb->prepare(
"SELECT * FROM $wpdb->posts WHERE post_status="publish" AND post_type=%s AND post_name=%s",
'flower',
$post_name
));
if( $post && isset($post->ID) ){
$wp->set_query_var( 'flower', $post->post_name );
$wp->set_query_var( 'post_type', 'flower' );
$wp->set_query_var( 'name', $post->post_name );
$wp->set_query_var( 'attachment', false );
$wp->set_query_var( 'error', false );
return;
}
}
}
Remove the pre_get_post hook
and use this one, but keep the post_type_link
hook as it is.