重写自定义POST分类以共享相同的URL路径(&T)

时间:2020-02-07 作者:Graeme Bryson

我有一个自定义分类法(video-category) 对于自定义帖子类型(video), 我正试图按照以下示例重写它们的路径:

发布(存档):about-us/video-center/category-name

职位(单一):about-us/video-center/category-name/post-title

重写后工作正常,使用:\'rewrite\' => array( \'slug\' => \'about-us/video-center/%category%\', \'with_front\' => false )

然而,分类页面给了我一个404错误,如下所示:\'rewrite\' => array( \'slug\' => \'about-us/video-center\', \'with_front\' => false );

我意识到,如果我将分类法的重写路径改为从“关于我们”以外的页面开始,这两个重定向都会起作用。不幸的是,我需要归档和发布页面都遵循完全相同的URL路径。

我已经为CPT和分类法创建了一个完整注册的gist,以及一个重写%category% 此处占位符:https://gist.github.com/graemebryson/92f5da5873a5edf0057d3b93b5cc4fdb

我已经阅读了大多数(如果不是全部的话)相关问题,但找不到任何允许分类法和重写后共享相同路径的内容。如果无法通过重写实现,我是否有其他选项来强制两者共享相同的URL路径?

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

(Revised on March 7th 2020 UTC)

因此共享相同的永久链接路径(或rewrite slug/base 如中所示example.com/<rewrite slug>/<term slug>example.com/<rewrite slug>/<post slug>) 是可能的,下面是(更新的)代码,您可以共享the exact same rewrite slug 在分类法和帖子类型之间:

function wpse_358157_parse_request( $wp ) {
    $path      = \'about-us/video-center\'; // rewrite slug; no trailing slashes
    $taxonomy  = \'video-category\';        // taxonomy slug
    $post_type = \'video\';                 // post type slug

    if ( preg_match( \'#^\' . preg_quote( $path, \'#\' ) . \'/#\', $wp->request ) &&
        isset( $wp->query_vars[ $taxonomy ] ) ) {
        $slug = $wp->query_vars[ $taxonomy ];
        $slug = ltrim( substr( $slug, strrpos( $slug, \'/\' ) ), \'/\' );

        if ( ! term_exists( $slug, $taxonomy ) ) {
            $wp->query_vars[\'name\']       = $wp->query_vars[ $taxonomy ];
            $wp->query_vars[\'post_type\']  = $post_type;
            $wp->query_vars[ $post_type ] = $wp->query_vars[ $taxonomy ];
            unset( $wp->query_vars[ $taxonomy ] );
        }
    }
}
add_action( \'parse_request\', \'wpse_358157_parse_request\' );

简要说明:

通过slug检查一个术语是否存在(比检查一个post是否存在)要容易得多,因此在上面的代码中,我们检查当前请求是否满足一个术语请求(即分类查询变量-例如。video-category — 存在于请求中,并且请求路径与分类法和post类型的重写slug匹配,如果是,则术语doesn\'t exist, 然后我们假设这是一个post请求。

一、 我们让WordPress将该请求视为一个帖子请求,而不是一个术语。

其他注意事项请确保您的帖子和术语不存在相同的问题。因为帖子和术语共享相同的重写段,所以无法知道我们应该加载帖子还是术语。

在最初的回答中,我提到分类法/术语permalink不能是分层的(例如。example.com/<rewrite slug>/<parent term slug>/<child term slug>/), 但实际上,它可以是分层的!我只是没有时间彻底测试一下……)

register_taxonomy( \'video-category\', \'video\', [
        \'rewrite\'      => [
            \'slug\'         => \'about-us/video-center\',
            \'with_front\'   => false,
            \'hierarchical\' => true, // enable hierarchical term permalink
        ],
        \'hierarchical\' => true,
        ...
    ]
);

因此,请尝试先注册分类法,然后注册post类型。如果这不起作用,那么首先注册post类型。

完整示例代码

function my_register_taxonomy() {
    register_taxonomy( \'video-category\', \'video\', [
            \'rewrite\'      => [
                \'slug\'         => \'about-us/video-center\',
                \'with_front\'   => false,
                \'hierarchical\' => true,
            ],
            \'hierarchical\' => true,
            \'labels\'       => [
                \'name\'          => \'Video Categories\',
                \'singular_name\' => \'Video Category\',
            ],
            \'show_in_rest\' => true,
        ]
    );
}

function my_register_post_type() {
    register_post_type( \'video\', [
            \'rewrite\'      => [
                \'slug\'       => \'about-us/video-center\',
                \'with_front\' => false,
            ],
            \'has_archive\'  => \'about-us/video-center\',
            \'hierarchical\' => true,
            \'public\'       => true,
            \'supports\'     => [ \'title\', \'editor\', \'page-attributes\' ],
            \'labels\'       => [
                \'name\'          => \'Videos\',
                \'singular_name\' => \'Video\',
            ],
            \'show_in_rest\' => true,
        ]
    );
}

add_action( \'init\', function () {
    my_register_taxonomy();
    my_register_post_type();

    /* If that doesn\'t work, you can try switching them:
    my_register_post_type();
    my_register_taxonomy();
    */
} );

function wpse_358157_parse_request( $wp ) {
    $path      = \'about-us/video-center\'; // rewrite slug; no trailing slashes
    $taxonomy  = \'video-category\';        // taxonomy slug
    $post_type = \'video\';                 // post type slug

    if ( preg_match( \'#^\' . preg_quote( $path, \'#\' ) . \'/#\', $wp->request ) &&
        isset( $wp->query_vars[ $taxonomy ] ) ) {
        $slug = $wp->query_vars[ $taxonomy ];
        $slug = ltrim( substr( $slug, strrpos( $slug, \'/\' ) ), \'/\' );

        if ( ! term_exists( $slug, $taxonomy ) ) {
            $wp->query_vars[\'name\']       = $wp->query_vars[ $taxonomy ];
            $wp->query_vars[\'post_type\']  = $post_type;
            $wp->query_vars[ $post_type ] = $wp->query_vars[ $taxonomy ];
            unset( $wp->query_vars[ $taxonomy ] );
        }
    }
}
add_action( \'parse_request\', \'wpse_358157_parse_request\' );

相关推荐

按元值日期(Desc或ASC)过滤Pre_Get_Posts中的帖子

我试图通过一个元值来排序帖子,但它并没有以正确的方式工作。我将日期存储在post meta值中,如下所示01 December 2019 10:00. 现在我想对帖子进行排序desc 或asc 就像date.我尝试了以下代码:$orderby = $query->get( \'orderby\' ); $sorting = $query->get( \'order\' ); if (\'month\' == $order