I have a custom post type called "services" with a category called "service_areas" and want to be able to pull up a page listing all of the "service_areas". I'm not exactly sure what this page would be called, because I believe that a "category archive page" would be a page listing all of the posts from a specific one of the "service_areas"s.

Calling the url domain-name.com/service_areas/a_service_category pulls up a category archive page for the a_service_category category as expected.

What is a good way to make domain-name.com/service_areas pull up a page listing all of the "service_areas" (as opposed to a 404)?

More Details:

The custom post type is services and it's custom taxonomy is services_category with a slug of service_areas:

 * Create Services CPT
function services_post_type() {

// Set UI labels for Custom Post Type
    $labels = array(
        'name'                => _x( 'Services', 'Post Type General Name', 'total' ),
        'singular_name'       => _x( 'Service', 'Post Type Singular Name', 'total' ),
        'menu_name'           => __( 'Services', 'total' ),
        'parent_item_colon'   => __( 'Parent Service', 'total' ),
        'all_items'           => __( 'All Services', 'total' ),
        'view_item'           => __( 'View Service', 'total' ),
        'add_new_item'        => __( 'Add New Service', 'total' ),
        'add_new'             => __( 'Add New', 'total' ),
        'edit_item'           => __( 'Edit Service', 'total' ),
        'update_item'         => __( 'Update Service', 'total' ),
        'search_items'        => __( 'Search Service', 'total' ),
        'not_found'           => __( 'Not Found', 'total' ),
        'not_found_in_trash'  => __( 'Not found in Trash', 'total' ),

    $args = array(
        'label'               => __( 'services', 'total' ),
        'description'         => __( 'Services we offer', 'total' ),
        'labels'              => $labels,
        'supports'            => array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', 'revisions' ),
        'hierarchical'        => true,
        'public'              => true,
        'show_ui'             => true,
        'show_in_menu'        => true,
        'show_in_nav_menus'   => true,
        'show_in_admin_bar'   => true,
        'menu_icon' => 'dashicons-businessman',
        'menu_position'       => 20,
        'can_export'          => true,
        'rewrite'            => array( 'slug' => 'services' ),
        'has_archive'         => true,
        'exclude_from_search' => false,
        'publicly_queryable'  => true,
        'capability_type'     => 'post',

    // Registering your Custom Post Type
    register_post_type( 'services', $args );


 * Register Caregiver category.
function register_categories() {

    // Define and sanitize options
    $name = __( 'Service Categories', 'total' );
    $slug = 'service_areas';

$args = array(
    'labels' => array(
        'name' => $name,
        'singular_name' => $name,
        'menu_name' => $name,
        'search_items' => __( 'Search','total' ),
        'popular_items' => __( 'Popular', 'total' ),
        'all_items' => __( 'All', 'total' ),
        'parent_item' => __( 'Parent', 'total' ),
        'parent_item_colon' => __( 'Parent', 'total' ),
        'edit_item' => __( 'Edit', 'total' ),
        'update_item' => __( 'Update', 'total' ),
        'add_new_item' => __( 'Add New', 'total' ),
        'new_item_name' => __( 'New', 'total' ),
        'separate_items_with_commas' => __( 'Separate with commas', 'total' ),
        'add_or_remove_items' => __( 'Add or remove', 'total' ),
        'choose_from_most_used' => __( 'Choose from the most used', 'total' ),
    'public' => true,
    'show_in_nav_menus' => true,
    'show_ui' => true,
    'show_tagcloud' => true,
    'hierarchical' => true,
    'rewrite' => array( 'slug' => $slug, 'with_front' => false ),
    'query_var' => true

    register_taxonomy( 'services_category', array( 'services' ), $args );


add_action( 'init', 'services_post_type', 0 );
add_action( 'init', 'register_categories', 0 );


I noticed that if I filter 'pre_get_posts', $query->query['name'] == 'service_areas' is true for that url. Possibly I could load a custom template based on that test and loop through get_terms( 'service_areas' ), but I'm not sure how.

  • @MaxYudin Yes. I also have category-service_areas.php. I think this theme might be preventing the templates from loading, but wouldn't that require the url to be category/service_areas so that WP know's we want a category archive page? – MikeiLL May 22 '17 at 19:03
  • Is service_areas a custom taxonomy? – Cedon May 22 '17 at 19:54
  • yes it is. i will update the answer with a couple of details... – MikeiLL May 22 '17 at 19:55
  • Post the full code of your custom taxonomy definition – Cedon May 22 '17 at 20:07
  • @belinus i believe that's all of it. It's actually done by public static methods in a class, but I don't imagine that matters. – MikeiLL May 22 '17 at 20:23

I would create a page in the admin panel called service areas and create a rewrite rule that tells wp to load a corresponding page-service-areas.php template.

function add_rewrite_rules () {
    add_rewrite_rule( '^service_areas/?$', 'index.php?pagename=service-areas', 'top' );
add_action('init', 'add_rewrite_rules');

Then in page-service-areas.php build out the query you want.

The following link helps you visualize how wordpress determines what page template to load:



  1. Add the above function (to themes functions.php or elsewhere).
  2. Flush rewrite rules by saving "settings -> permalinks"
  3. In the admin panel, create a blank page called "Service Areas".
  4. Create a file in the theme with the content you want to load. (copy of page.php, archive.php or some other loop or content).

Now you should be able to click on the link for the page you created in admin (yoursite.com/service-areas) OR—thanks to our rewrite rule—(yoursite.com/service_areas) and see your template page.

  • Not implementing so far. I have changed permalink settings to Plain and created a document in the main theme directory named page-service-areas.php and flushed rewrite rules (which I imagine wouldn't matter for plain permalink settings). When the url is domain-name.com/?pagename=service-areas, it still comes up as a 404. Have tried this with custom theme as well as twentythirteen. – MikeiLL May 22 '17 at 22:16
  • haven't tested the code out but in theory what you're telling wordpress is that when a user lands on domain.com/service_areas/, load the page-service-areas.php template – eballeste May 22 '17 at 22:34
  • also, it's important that you create an actual page with service_areas as it's slug for this to work – eballeste May 22 '17 at 22:36
  • What do you mean by "actual page with service_areas as it's slug"? That's something different than the page-service-areas.php template? – MikeiLL May 22 '17 at 22:45
  • 1
    Yeah, it will definitely load the template even without the rewrite rule because wordpress will, by default, look for a template called page-pagename.php for a page with slug pagename, the rewrite rule was to force wordpress to skip loading the service_areas archive page and load the page with it's template instead... not sure how to make it work in your particular case though but i guess you figured it out? – eballeste May 22 '17 at 23:04

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.