2

I have two Events custom post types that I want to show up under the same permalink structure, eg: example.com/events/4560/an-event

Is this possible? I have tried coding it myself and using the Custom Post Type Permalinks plugin but one of the two CPTs always returns a 404 error.

2

When two post types with the same permalink structure is registered they are added to rewrite rule array with the same index. If you want to add two elements with the same index to php array first element will be overwritten. Your rewrites will be only working for only one post type, second one.

To display posts from first post type you have tell WordPress which post type to choose. To find it out you must query database for post from both post types and check which post type current post type has.

I hope that following code will help you understand what is going on.

/**
 * Register event 1 post type
 *
 * Method is used by init hook
 */
function wpse_287785_register_event_1_post_type() {

    $labels = array(
        'name' => __( 'Events' ),
        'singular_name' => __( 'Event' ),
        'add_new' => __( 'Add new' ),
        'add_new_item' => __( 'Add new' ),
        'edit_item' => __( 'Edit' ),
        'new_item' => __( 'New' ),
        'view_item' => __( 'View' ),
        'search_items' => __( 'Search' ),
        'not_found' => __( 'Not found' ),
        'not_found_in_trash' => __( 'Not found Events in trash' ),
        'parent_item_colon' => __( 'Parent' ),
        'menu_name' => __( 'Events' ),

    );

    $args = array(
        'labels' => $labels,
        'hierarchical' => false,
        'supports' => array( 'title', 'page-attributes' ),
        'taxonomies' => array(),
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'show_in_nav_menus' => false,
        'publicly_queryable' => true,
        'exclude_from_search' => false,
        'has_archive' => true,
        'query_var' => true,
        'can_export' => true,
        'rewrite' => array('slug' => 'event'),
        'capability_type' => 'post',
    );

    register_post_type( 'event_1', $args );
}

add_action( 'init', 'wpse_287785_register_event_1_post_type' );

/**
 * Register event 2 post type
 *
 * Method is used by init hook
 */
function wpse_287785_register_event_2_post_type() {

    $labels = array(
        'name' => __( 'Events' ),
        'singular_name' => __( 'Event' ),
        'add_new' => __( 'Add new' ),
        'add_new_item' => __( 'Add new' ),
        'edit_item' => __( 'Edit' ),
        'new_item' => __( 'New' ),
        'view_item' => __( 'View' ),
        'search_items' => __( 'Search' ),
        'not_found' => __( 'Not found' ),
        'not_found_in_trash' => __( 'Not found Events in trash' ),
        'parent_item_colon' => __( 'Parent' ),
        'menu_name' => __( 'Events' ),

    );

    $args = array(
        'labels' => $labels,
        'hierarchical' => false,
        'supports' => array( 'title', 'page-attributes' ),
        'taxonomies' => array(),
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'show_in_nav_menus' => false,
        'publicly_queryable' => true,
        'exclude_from_search' => false,
        'has_archive' => true,
        'query_var' => true,
        'can_export' => true,
        'rewrite' => array('slug' => 'event'),
        'capability_type' => 'post',
    );

    register_post_type( 'event_2', $args );
}

add_action( 'init', 'wpse_287785_register_event_2_post_type' );

/**
 * Check if post exits as event_1 post type or as event_2 post type.
 */
function wpse_287785_parse_request($query_vars) {

    if( !is_admin() ) { // Do not parse request on admin.

        $slug = ( isset( $query_vars['name'] ) && !empty( $query_vars['name'] ) ) ? $query_vars['name'] : false;

        if($slug) {

            // Check if post exits as event_1 or event_2 post type
            $query = new WP_Query(array(
                'post_type' => array('event_1', 'event_2'),
                'name' => $slug,
            ));

            if( $query->have_posts() ) {

                $post_type = $query->post->post_type;

                // Overwrite query vars for current post type
                $query_vars = array(
                    'page' => '',
                    $post_type => $slug,
                    'post_type' => $post_type,
                    'name' => $slug,
                );

                return $query_vars;
            }
        }
    }

    return $query_vars;
}

add_filter( 'request', 'wpse_287785_parse_request' );
  • Fantastic, that seems to be working. I was worried it wouldn't even be possible. Thanks – chris_huh Dec 5 '17 at 13:04
  • Most impressive. – MastaBaba Dec 29 '17 at 15:27

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.