Site icon Hip-Hop Website Design and Development

How to query 2 custom post types that need to share a slug?

I’m trying to make 2 custom post types (authors and works) share the same slug. The authors CPT uses an archive page which functions properly, but works CPT does not need one.

CPT 1: https://domain.com/library/authors/author-name/

CPT 2: https://domain.com/library/authors/author-name/works-name/

The permalink rewrite I cobbled together is functional. It pulls the author post ID from a custom meta menu in the works CPT post and then builds the permalink. However, I get a 404 error when visiting a works link because WordPress can’t find the works post in the database due to the sharing of slugs.

What I can’t figure out is how to query the works post so it can go around usual query that fails and locate the post. I tried the only 2 examples I found on here and stackoverflow, but they aren’t working. I tried changing authors CPT to hierarchical (just in case) but didn’t seem to matter. Been at this for days and this type of stuff is way over my head, so maybe I’m just blind to the obvious.

Post Creation Code

////////////////////////////////
//////// Works POST TYPE
function works_post_type() {
    $labels = array(
        'name'                  => _x( 'Works', 'Post Type General Name', 'text_domain' ),
        'singular_name'         => _x( 'Work', 'Post Type Singular Name', 'text_domain' ),
        'menu_name'             => __( 'Works', 'text_domain' ),
        'name_admin_bar'        => __( 'Works', 'text_domain' ),
        'archives'              => __( 'Works Archives', 'text_domain' ),
        'parent_item'           => null,
        'parent_item_colon'     => null,
        'all_items'             => __( 'All Works', 'text_domain' ),
        'add_new_item'          => __( 'Add New Work', 'text_domain' ),
        'add_new'               => __( 'Add New Work', 'text_domain' ),
        'new_item'              => __( 'New Work', 'text_domain' ),
        'edit_item'             => __( 'Edit Work', 'text_domain' ),
        'update_item'           => __( 'Update Work', 'text_domain' ),
        'view_item'             => __( 'View Work', 'text_domain' ),
        'search_items'          => __( 'Search Works', 'text_domain' ),
        'not_found'             => __( 'Works Not found', 'text_domain' ),
        'not_found_in_trash'    => __( 'Works Not found in Trash', 'text_domain' ),
        'featured_image'        => __( 'Featured Image', 'text_domain' ),
        'set_featured_image'    => __( 'Set featured image', 'text_domain' ),
        'remove_featured_image' => __( 'Remove featured image', 'text_domain' ),
        'use_featured_image'    => __( 'Use as featured image', 'text_domain' ),
        'insert_into_item'      => __( 'Insert into Work', 'text_domain' ),
        'uploaded_to_this_item' => __( 'Uploaded to this Work', 'text_domain' ),
        'items_list'            => __( 'Works list', 'text_domain' ),
        'items_list_navigation' => __( 'Works list navigation', 'text_domain' ),
        'filter_items_list'     => __( 'Filter Works items list', 'text_domain' ),
    );
    $args = array(
        'label'                 => __( 'Works', 'text_domain' ),
        'description'           => __( 'Written works', 'text_domain' ),
        'labels'                => $labels,
        'supports'              => array( 'title', 'editor', 'excerpt', 'thumbnail', 'revisions', 'custom-fields', 'comments', 'page-attributes'),
        'taxonomies'            => array( 'post_tag' ),
        'hierarchical'          => true,
        'public'                => true,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'menu_position'         => 2,
        'menu_icon'             => 'dashicons-book-alt',
        'show_in_admin_bar'     => true,
        'show_in_nav_menus'     => true,
        'can_export'            => true,
        'has_archive'           => false,
        'exclude_from_search'   => false,
        'publicly_queryable'    => true,
        'query_var'             => true,
        'capability_type'       => 'post',
    );
    register_post_type( 'works', $args );
}
add_action( 'init', 'works_post_type', 0 );
////////////////////////////////
//////// AUTHOR POST TYPE
function authors_post_type() {
    $labels = array(
        'name'                  => _x( 'Authors', 'Post Type General Name', 'text_domain' ),
        'singular_name'         => _x( 'Author', 'Post Type Singular Name', 'text_domain' ),
        'menu_name'             => __( 'Authors', 'text_domain' ),
        'name_admin_bar'        => __( 'Authors', 'text_domain' ),
        'archives'              => __( 'Authors Archives', 'text_domain' ),
        'parent_item'           => null,
        'parent_item_colon'     => null,
        'all_items'             => __( 'All Authors', 'text_domain' ),
        'add_new_item'          => __( 'Add New Author', 'text_domain' ),
        'add_new'               => __( 'Add New Author', 'text_domain' ),
        'new_item'              => __( 'New Author', 'text_domain' ),
        'edit_item'             => __( 'Edit Author', 'text_domain' ),
        'update_item'           => __( 'Update Author', 'text_domain' ),
        'view_item'             => __( 'View Author', 'text_domain' ),
        'search_items'          => __( 'Search Authors', 'text_domain' ),
        'not_found'             => __( 'Authors Not found', 'text_domain' ),
        'not_found_in_trash'    => __( 'Authors Not found in Trash', 'text_domain' ),
        'featured_image'        => __( 'Featured Image', 'text_domain' ),
        'set_featured_image'    => __( 'Set featured image', 'text_domain' ),
        'remove_featured_image' => __( 'Remove featured image', 'text_domain' ),
        'use_featured_image'    => __( 'Use as featured image', 'text_domain' ),
        'insert_into_item'      => __( 'Insert into Author', 'text_domain' ),
        'uploaded_to_this_item' => __( 'Uploaded to this Author', 'text_domain' ),
        'items_list'            => __( 'Authors list', 'text_domain' ),
        'items_list_navigation' => __( 'Authors list navigation', 'text_domain' ),
        'filter_items_list'     => __( 'Filter Authors items list', 'text_domain' ),
    );
    $args = array(
        'label'                 => __( 'Authors', 'text_domain' ),
        'description'           => __( 'Written authors', 'text_domain' ),
        'labels'                => $labels,
        'supports'              => array( 'title', 'thumbnail', 'editor', 'revisions', 'custom-fields'),
        'taxonomies'            => array( 'post_tag' ),
        'hierarchical'          => true,
        'public'                => true,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'menu_position'         => 2,
        'menu_icon'             => 'dashicons-businessperson',
        'show_in_admin_bar'     => true,
        'show_in_nav_menus'     => true,
        'can_export'            => true,
        'has_archive'           => true,        
        'exclude_from_search'   => false,
        'publicly_queryable'    => true,
        'query_var'             => true,
        'rewrite'               => array('slug' => 'library/authors'),
        'capability_type'       => 'post',
    );
    register_post_type( 'authors', $args );
}
add_action( 'init', 'authors_post_type', 0 );
add_theme_support( 'post-thumbnails', array( 'authors' ) );

Permalink Rewrite (works)

add_filter( 'post_type_link', 'my_website_filter_post_type_link', 1, 4 );
function my_website_filter_post_type_link( $post_link, $post, $leavename, $sample ) {
    switch( $post->post_type ) {

        case 'works':

            $author_id = get_post_meta( $post->ID, 'wrks_author', true);
            $author = basename(get_permalink($author_id));
            if ( $author !== '' ) {

                // create the new permalink
                $post_link = home_url( user_trailingslashit( 'library/authors/' . $author . '/' . $post->post_name ) );
            }

            break;

    }
    return $post_link;
}

Query Fix Option 1 (failed)

add_filter('request', 'overwriteQueryVars', 10, 1);

function overwriteQueryVars($query)
{
    if ( empty($query['post_type']) || $query['post_type']!='authors' ) {
        return $query;
    }

    $sql = "SELECT ID FROM wp_posts WHERE post_type='authors' and post_name='%s'";
    $post_name = urlencode($query['name']);

    if ( in_authors_but_not_works ) {
        return $query;
    }

    $post_name = $query->request;
    $postType = 'works';
    
    $query = array (
        'page' => '',
        'works' => $post_name,
        'post_type' => $postType,
        'name' => $post_name,
    );

}

Query Fix Option 2 (failed)

add_action('parse_request', 'overwriteRequest', 10, 1);
function overwriteRequest($query) {

    if ( count($query->query_vars) > 0 && empty($query->query_vars['post_type'])) {

        $pageName = preg_replace('/library/authors//', '', $query->request);
        $postType = 'works';

        $result = get_posts(array(
            'post_type' => $postType,
            'name' => $pageName
        ));

        if (count($result) < 1) {

            return $query;

        } else {
            $new_query = array(
                'page' => '',
                'works' => $pageName,
                'post_type' => $postType,
                'name' => $pageName
            );
            $query->query_vars = $new_query;
            return $query;
        }

    } else {
        return $query;
    }
}