WordPress uses Rewrite Rules to parse the request. It means that if the request matches one of the rule, it will be parsed using that rule.
The rule for pages is one of the last rule made to catch most of the requests that didn't match any earlier rules. So if you add your CPT without any slug, then pages rule won't be fired up...
One way to fix this is to register CPT with a slug and then change their links and WPs behavior. Here's the code:
function register_mycpt() {
$arguments = array(
'label' => 'MyCPT',
'public' => true,
'hierarchical' => false,
...
'has_archive' => false,
'rewrite' => true
);
register_post_type('mycpt', $arguments);
}
add_action( 'init', 'register_mycpt' );
Now the URLs for these posts will look like these:
http://example.com/mycpt/{post_name}/
But we can easily change this using post_type_link
filter:
function change_mycpt_post_type_link( $url, $post, $leavename ) {
if ( 'mycpt' == $post->post_type ) {
$url = site_url('/') . $post->post_name . '/';
}
return $url;
}
add_filter( 'post_type_link', 'change_mycpt_post_type_link', 10, 3 );
Now the URLs will be correct, but... They won't work. They will be parsed using rewrite rule for pages and will cause 404 error (since there is no page with such URL). But we can fix that too:
function try_mycpt_before_page_in_parse_request( $wp ) {
global $wpdb;
if ( is_admin() ) return;
if ( array_key_exists( 'name', $wp->query_vars ) ) {
$post_name = $wp->query_vars['name'];
$id = $wpdb->get_var( $wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_name = %s ",
'mycpt', $post_name
) );
if ( $id ) {
$wp->query_vars['mycpt'] = $post_name;
$wp->query_vars['post_type'] = 'mycpt';
}
}
}
add_action( 'parse_request', 'try_mycpt_before_page_in_parse_request' );
PS. Is it wise to use that code? That's another question. It changes behavior of WP in rather major way, so it can be a little bit tricky. But if there is really a need, you can do this...
Disclaimer: This code will work fine for nonhierarchical CPTs, but you can adapt it to work for hierarchical also...