I've tried various methods posted here and on stackoverflow and none of them work unfortunately.

My CPT is "service_locations" and by default has this structure for main pages:


and this structure for the service page(s) for each city:


Here is how i'm declaring my CPT:

add_action( 'init', 'service_locations' );
function service_locations() {
    register_post_type('service_locations', array(
        'label' => 'Service Areas',
        'description' => '',
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'capability_type' => 'post',
        'hierarchical' => true,
        'rewrite' => true,
        'query_var' => true,
        'exclude_from_search ' => true,
        'has_archive' => true,
        'supports' => array(

What i need/want is this type of URL structure:




Using this method: http://www.markwarddesign.com/2014/02/remove-custom-post-type-slug-permalink/ i was able to get just /city-name/ to show with no further conflicts. However, the child-page of "city-name" just goes 404.

// Remove the slug from published post permalinks. Only affect our CPT though.
function vipx_remove_cpt_slug( $post_link, $post, $leavename ) {
    if ( ! in_array( $post->post_type, array( 'service_locations' ) ) || 'publish' != $post->post_status )
        return $post_link;
    $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
    return $post_link;
add_filter( 'post_type_link', 'vipx_remove_cpt_slug', 10, 3 );

function vipx_parse_request_tricksy( $query ) {
    if ( ! $query->is_main_query() )

    if ( 2 != count( $query->query )
        || ! isset( $query->query['page'] ) )

    if ( ! empty( $query->query['name'] ) )
        $query->set( 'post_type', array( 'post', 'service_locations', 'page' ) );
add_action( 'pre_get_posts', 'vipx_parse_request_tricksy' );

Another issue i'm seeing is that this will ONLY work if you've set your permalink structure to /%postname%/, but because the site will also have a blog the potential for conflicts increases greatly. Ideally, i'd like to be able to show all blog posts as /blog/some-post-name/ and have my city pages and their respective service type child-pages show as above. Any help here is greatly appreciated.

  • This is not an answer, just a recommendation. I think you should have a "services" custom post with "location" taxonomy. Think about it. You have the custom post type "service_locations" but the content type is not a service location, it is a service. The location is a classification method, something that can be used to group services. So, locations should be a taxonomy and services the post type. – cybmeta Sep 2 '14 at 19:42
  • Thank you, that's a great recommendation and makes perfect sense, however for SEO purposes (yup...) the client is requesting each "location" to have service sub-pages so they can have location specific content related to each service and also keep it unique. In other words, lots of content everywhere. That's why, unfortunately, taxonomies would not work here. – blueplasma_dev Sep 2 '14 at 20:20
  • Or what i should have said is: unique service content for each location – blueplasma_dev Sep 2 '14 at 20:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.