一种基于ACF字段值的动态CPT永久链路结构

时间:2018-11-21 作者:Momondo

关于这个话题的问题已经很少了,但它们对我的问题没有帮助。所以我想要实现的是基于ACF(radio)值的动态CPT permalink结构。

// _cb stands for checkbox
radio_acf_cb = foo
radio_acf_cb = bar
根据用户的选择,permalink将如下所示

// fixed_word is the first part of the permalink which will be static
// foo/bar are the values based on the choice from the ACF
// 123 is the post ID 

example.com/fixed_word/foo/123 // if foo is chosen
example.com/fixed_word/bar/123 // if bar is chosen
以下是我迄今为止所做的尝试:

add_filter( \'post_type_link\', \'so51217355_post_type_link\', 10, 2 );

function so51217355_post_type_link( $permalink, $post ) {

    if ( \'my_cpt\' === $post->post_type ) {

        $choice = get_field(\'foo_bar\', $post->ID) // foo or bar

        $choice_slug = $choice == \'foo\' ? $choce : \'bar\';


        if ( $choice_slug ) {
            // This would give me example.com/fixed_word/foo/123
            // or example.com/fixed_word/bar/123
            $permalink = \'/fixed_word/\' . $choice_slug . $post->ID;
        }

    }

    return $permalink;
}
现在我知道我需要用add_rewrite_rule() 但我不知道如何设置条件。

1 个回复
SO网友:Milo

第一步是注册post类型。slug在这里并不重要,我们不会使用注册post类型时生成的任何规则。

在此相同范围内init 函数中,我们添加了一个重写标记,并使用permalink模式进行了permastruct。这将使我们很容易在稍后添加的过滤器中构造永久链接。

最后一位是将传入请求映射到正确查询变量的重写规则。要按帖子ID查询自定义帖子类型,需要设置post_typep 查询变量。

function wpd_test_cpt() {

    $args = array(
        \'label\' => \'My CPT\',
        \'public\' => true,
        \'rewrite\' => [
            \'slug\' => \'my_cpt\',
            \'with_front\' => false,
        ],
    );
    register_post_type( \'my_cpt\', $args );

    add_rewrite_tag( \'%foo_or_bar%\', \'([^/]+)\' );
    add_permastruct( \'my_cpt\', \'fixed-word/%foo_or_bar%/%post_id%/\' );
    add_rewrite_rule(
        \'fixed-word/([^/]+)/([0-9]+)/?$\',
        \'index.php?post_type=my_cpt&foo_or_bar=$matches[1]&p=$matches[2]\',
        \'top\'
    );

}
add_action( \'init\', \'wpd_test_cpt\' );
下一步是post_type_link 为占位符交换值的过滤器:

function wpd_test_post_type_link( $permalink, $post ) {
    if ( \'my_cpt\' === $post->post_type ) {
        if( $choice = get_field( \'foo_or_bar\', $post->ID ) ) {
            $permalink = str_replace( [\'%foo_or_bar%\', \'%post_id%\'], [$choice, $post->ID], $permalink );
        }
    }
    return $permalink;
}
add_filter( \'post_type_link\', \'wpd_test_post_type_link\', 10, 2 );
现在这一切都应该按原样进行,但你可能会注意到一个小怪癖——你可以改变foobar 无论您想要什么,查询仍然成功。你不能通过元数据来优化单一视图,WordPress认为帖子是存在的,而不仅仅是ID或slug。

要改变这一点,我们可以添加一些代码来检查foo_or_bar ,并确保它与请求的帖子ID匹配。如果不匹配,我们将重定向到正确的URL:

function wpd_test_pre_get( $query ) {
    if ( isset( $query->query[\'foo_or_bar\'] ) && isset( $query->query[\'p\'] ) ) {
        if( $choice = get_field( \'foo_or_bar\', $query->query[\'p\'] ) ){
            if( $choice != $query->query[\'foo_or_bar\'] ){
                wp_redirect( get_permalink( $query->query[\'p\'] ) );
            }
        }
    }
}
add_action( \'pre_get_posts\', \'wpd_test_pre_get\' );

结束

相关推荐

Let me choose permalinks

我需要选择一个叫做“mysite”的永久链接。com/1418”,但wordpress不断在永久链接中添加“-2”。通常这意味着我已经有了一个名为“相同”的页面,它位于垃圾箱或其他地方。但这里的情况似乎并非如此。我尝试在设置中重置永久链接,这也没有帮助。我如何使用数字作为页面名称permalink,而不用wordpress在permalink中添加“-2”。