如何查询需要共享一个插件的2个自定义帖子类型?

时间:2021-08-24 作者:liquidRock

我试图让两个自定义帖子类型(作者和作品)共享相同的slug。作者CPT使用功能正常的归档页,但works CPT不需要。

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

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

我拼凑的permalink重写是功能性的。它从works CPT帖子中的自定义元菜单中提取作者帖子ID,然后构建永久链接。然而,我在访问works链接时遇到了404错误,因为WordPress由于共享段塞而无法在数据库中找到works帖子。

我搞不懂的是如何查询works帖子,这样它就可以绕过通常失败的查询并找到帖子。我尝试了在这里和stackoverflow上找到的仅有的两个示例,但它们都不起作用。我尝试将作者CPT改为层次结构(以防万一),但似乎没什么关系。我已经做了好几天了,这类事情让我不知所措,所以也许我只是对显而易见的事情视而不见。

创建后代码

////////////////////////////////
//////// 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重写(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;
}

查询修复选项1(失败)

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,
    );

}

查询修复选项2(失败)

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;
    }
}

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

请注意,过滤器回调必须始终返回通常是传递给回调的第一个参数。比如你的overwriteQueryVars() 函数,它必须始终返回$query 因为request 是一个过滤器挂钩。

其次,不要覆盖整个查询参数(例如$query = array( ... )$query->query_vars = $new_query;), 您应该只更改现有查询参数中需要更改的参数,例如。$query[\'post_type\'] = $postType;.

但无论如何,试试这个对我来说很有效的方法:

add_filter( \'request\', \'overwriteQueryVars\' );
function overwriteQueryVars( $query_vars ) { // I renamed $query to $query_vars.
    global $wp;

    /*
     * 1. Check if the current page URL path begins with library/authors/ as in example.com/library/authors/
     * 2. Then check if the post_type is exactly "authors".
     * 3. Finally, check if the "authors" is in the form of <slug>/<slug>.
     */
    if ( preg_match( \'#^library/authors/#\', $wp->request )        &&
        isset( $query_vars[\'post_type\'], $query_vars[\'authors\'] ) &&
        \'authors\' === $query_vars[\'post_type\']                    &&
        preg_match( \'#^([^/]+)/([^/]+)$#\', $query_vars[\'authors\'] )
    ) {
        $works_slug = explode( \'/\', $query_vars[\'authors\'] )[1];

        // Find "works" post with the above slug.
        $ids = get_posts( array(
            \'post_type\' => \'works\',
            \'name\'      => $works_slug,
            \'fields\'    => \'ids\',
        ) );

        // If the post exists, then load it.
        if ( ! empty( $ids ) ) {
            $query_vars[\'post_type\'] = \'works\';
            $query_vars[\'name\'] = $query_vars[\'works\'] = get_page_uri( $ids[0] );

            unset( $query_vars[\'authors\'] );
        }
    }

    return $query_vars; // ALWAYS RETURN IT
}
此外,在post_type_link 过滤回调,我会:

更改\'library/authors/\' . $author . \'/\' . $post->post_name\'library/authors/\' . $author . \'/\' . ( $leavename ? \'%postname%\' : $post->post_name ) 确保后期permalink(段塞零件)可通过后期编辑屏幕(中)进行编辑wp-admin).

更改$author = basename(get_permalink($author_id));$author = $author_id ? get_post_field( \'post_name\', $author_id ) : \'\';.

很抱歉,我忘记了预览URL(例如,对于状态为draftpending) 其中URL不是;“漂亮”;看起来像https://example.com/?post_type=works&p=123&preview=true.

因此,为了确保返回的URL是正确的my_website_filter_post_type_link() 函数,在最顶部添加:

if ( $sample || wp_force_plain_post_permalink( $post ) ) {
    return $post_link;
}
一、 e.将其添加到具有switch( $post->post_type ).

如果您的works 职位类型不是层次结构,请替换get_page_uri( $ids[0] ) 具有$works_slug.