重写附加到另一个自定义帖子类型的自定义帖子类型的规则

时间:2017-04-22 作者:Nathan Johnson

我有两种自定义的帖子类型:让我们调用它们locationtopic. 位置自定义帖子类型是分层的。所有文章都使用post meta“附加”到单个位置。如果有关系topic post类型有一个自定义元框,其中包含locations 使用以下方法保存:

update_post_meta( $post->ID, \'my-prefix-location\', $the_location );
我想重写位置,以便他们的URLhttps://my.domain.tld/location/sub-location/sub-sub-location/topic/.

对于位置,在注册post类型时,我尝试使用以下重写参数:

\'rewrite\' => [ \'slug\' => \'/\', \'with_front\' => false, ],
这对于位置来说很好,但我无法访问任何主题,即使在手动刷新重写规则之后。如果我用/?id=100, 它们重定向到/topic/slug/ (这不是我想要的URL结构),但结果是404。

但即使我解决了这个问题,我也不知道如何重写主题的URL,以便它们具有前面附加位置的结构。

我想我必须add_rewrite_rule() 和/或add_rewrite_endpoint(). 我以前从未实际使用过这两个函数中的任何一个。任何指点都将不胜感激。我是不是走错了方向?

【新增】

因此,我认为我不能轻易地(甚至根本不能)做我想做的事情。我现在一直在尝试的是让我的永久链接:

/topic/directory/to/my/location/page_name/
添加重写规则可以很容易地忽略除最后一个参数以外的所有参数,并在该参数上进行匹配:

add_rewrite_rule( \'topic/(.*)/([^/]+)/?$\', \'index.php?topic=$matches[2]\', \'top\' );
这很好,除了我希望规范URL具有(.*)作为主题所附加类别的层次URL结构,并具有所有其他topic/*/leaf/ URL重定向到此URL。

我很难弄清楚如何做到这一点,或者即使这是可能的。

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

WordPress重写规则的工作方式(有几个特殊的例外),不同的内容类型在其URL中有某种独特的元素,使WP能够在数据库中查找并查找之前识别它要查找的内容类型。例如,给定URL:

/topic/one/two/three/
你不能肯定地说three 如果位置和主题共享相同,则为位置或主题topic

这就是说,复杂的部分是您需要手动解决这种歧义。这有一个缺点——对于可能是主题的每个请求都需要对数据库进行额外的查询,这不是一个主要问题,但需要注意。

在最初的问题中,您表示希望删除自定义帖子类型基。我在这里给出的答案很有用topic 作为基础。移除会引发page 在整个组合中输入。你也许可以用这个解决方案来解决这个问题,但为了向你展示这个问题的最简单形式,我不打算这么做。

步骤1添加新的%parent_location% 重写将作为主题位置占位符的标记。这发生在init 按照规则采取行动:

add_rewrite_tag( \'%parent_location%\', \'(.+)\' );
第二步注册帖子类型。我将省去基本的东西,重点放在实现这一目标的具体部分。这一切都发生在init 行动也是如此。添加这些规则后,不要忘记刷新重写规则。

对于位置,根段塞为topic, 并且岗位类型是分级的。

$args = array(
    \'rewrite\' => array( \'slug\' => \'topic\' ),
    \'hierarchical\' => true,
    // ... your other args
);
register_post_type( \'location\', $args );
对于主题,我们将%parent_location% 重写slug中的标记。我们将使用它替换URL中的位置。这样生成的重写规则实际上永远不会匹配,但它使下一步更容易。

$args = array(
    \'rewrite\' => array( \'slug\' => \'topic/%parent_location%\' ),
    // ... your other args
);
register_post_type( \'topic\', $args );
步骤3将过滤器添加到post_type_link 为我们的%parent_location% 每当请求此主题的永久链接时,标记。看看评论,看看发生了什么。

function wpd_topic_link( $link, $post ) {
    // if this is a topic post
    if ( $post->post_type === \'topic\' ) {
        // if there is location ID meta saved for this post under parent_location key
        if( $location_id = get_post_meta( $post->ID, \'parent_location\', true ) ){
            // query for that post to make sure it exists
            $location_post = get_posts( array( \'post_type\' => \'location\', \'p\' => $location_id ) );
            if( !empty( $location_post ) ){
                // get the location permalink
                // strip out everything except the location parts of the URL
                // substitute that value for our %parent_location% placeholder
                $location_link = get_permalink( $location_post[0] );
                $location_path = untrailingslashit( str_replace( home_url( \'/topic/\' ), \'\', $location_link ) );
                $link = str_replace( \'%parent_location%\', $location_path, $link );
            }
        }
    }
    return $link;
}
add_filter( \'post_type_link\', \'wpd_topic_link\', 20, 2 );
现在,当您添加一篇主题文章并在文章元中保存一个有效的位置ID时,您将在编辑该主题文章时看到URL中反映的路径。

步骤4过滤器request 查找对实际可能是主题的位置的任何请求。通读评论以了解发生了什么。这里要注意的另一个副作用是,你永远不会有一个位置弹头,这也是一个主题。

function wpd_locations_may_be_topics( $request ){
    // if the location query var is set
    if( isset( $request[\'location\'] ) ){
        // location will be a parent / child hierarchy
        // make it an array of URL segments
        $parts = explode( \'/\', $request[\'location\'] );
        // it might be a topic only if there\'s more than a single segment
        if( count( $parts ) > 1 ){
            $topic_slug = end( $parts );
            $maybe_topic = get_posts( array( \'post_type\' => \'topic\', \'name\' => $topic_slug ) );
            // if a topic was returned
            if( !empty( $maybe_topic ) ){
                // change request from location to topic    
                unset( $request[\'location\'] );
                $request[\'post_type\'] = \'topic\';
                $request[\'topic\'] = $topic_slug;
            }
        }
    }
    return $request;
}
add_filter( \'request\', \'wpd_locations_may_be_topics\' );

相关推荐