层次化自定义帖子类型的自定义重写规则

时间:2016-01-15 作者:Kuuak

在客户网站工作时,我遇到了我最大的敌人。。。WP URL重写:(。我实际上无法理解,经过许多天的尝试和搜索,我无法使其工作。

我想得到的是像这样的永久链接company.com/product/%product-name%/ 无论/parent/child/ 嵌套深度。出于其他原因,我确实需要层次页面的功能,但它不应该出现在URL中。

这是我的设置:

Wordpress 4.4.1永久链接设置设置为Post name

我创建了一个分层自定义帖子类型product 将rewrite参数设置为false。

$args = array(
    \'label\'                 => __( \'Product\', \'domain\' ),
    \'description\'           => __( \'Company products\', \'domain\' ),
    \'labels\'                => $labels,
    \'supports\'              => array( \'title\', \'editor\', \'excerpt\', \'thumbnail\', \'revisions\', \'page-attributes\' ),
    \'taxonomies\'            => array( \'category\', \'post_tag\' ),
    \'hierarchical\'          => true,
    \'public\'                => true,
    \'show_ui\'               => true,
    \'show_in_menu\'          => true,
    \'menu_position\'         => 5,
    \'show_in_admin_bar\'     => true,
    \'show_in_nav_menus\'     => false,
    \'can_export\'            => true,
    \'has_archive\'           => true,
    \'exclude_from_search\'   => false,
    \'publicly_queryable\'    => true,
    \'rewrite\'               => false,
    \'capability_type\'       => \'page\',
);
register_post_type( \'product\', $args );
此时,产品没有很好的永久性,它们看起来像这样,而且都能工作:

第一级:company.com/?product=my-first-product -> 好的,第二级:company.com/?product=my-first-product/child-product -> 确定之后,我注册了重写规则和permastruct,然后通过在permalink设置页面中保存更改来刷新重写规则

    function bvt_product_rewrite_rule() {
        add_rewrite_rule( 
            \'^product/([^/]+)/?$\',
            \'index.php?post_type=product&pagename=$matches[1]\',
            \'top\'
        );
        add_permastruct( \'product\', \'/product/%product%/\' );
    }
    add_action( \'init\', \'bvt_product_rewrite_rule\', 10 );
现在,permalinks在第一级页面中正确显示,但在子页面中不正确。两个级别都给了我一个404错误。

第一级:company.com/product/my-first-product/ -> 404第二级:company.com/product/my-first-product/child-product/ -> 404我也尝试了这里给出的解决方案https://wordpress.stackexchange.com/a/101077/86838 它允许从子permalink中删除父slug,但我仍然没有成功

function bvt_product_flatten_hierarchies( $post_link, $post ) {
    if ( \'product\' != $post->post_type ) {
        return $post_link;
    }

    $uri = \'\';
    foreach ( $post->ancestors as $parent ) {
        $uri = get_post( $parent )->post_name . "/" . $uri;
    }

    return str_replace( $uri, \'\', $post_link );
}
add_filter( \'post_type_link\', \'bvt_product_flatten_hierarchies\', 10, 2 );
我安装了两个插件debug-barmonkeyman-rewrite-analyzer 分析重写和查询,但我一直无法使其工作。

我最后一次尝试是wp-permastructure 允许将自定义永久链接设置为自定义帖子类型的插件。启用自定义设置permastructrewrite 的数组选项register_post_type.

[...]
\'publicly_queryable\'    => true,
\'rewrite\'               => array(
    \'permastruct\'   => \'/%postname%/\',
),
\'capability_type\'       => \'page\',
[...]
使用此设置和之前的自定义重写/置换/展平\\u层次结构,它可以按照插件描述的方式工作

第一级:company.com/my-first-product/ -> 好的,第二级:company.com/child-product/ -> 好的,但是现在/product/ 缺少级别,如果我尝试将其放入\'permastruct\' => \'/product/%postname%/\' 配置它让我回到404错误。

这就引出了我的主要问题。

使用最新的插件是否可以完成我需要的任务,或者是否可以尽可能地接近?

感谢所有愿意花时间回答我的人,也许能把我从困境中解救出来。谢谢

PS我不能在正文中插入两个以上的链接,下面是提到的插件链接:

https://wordpress.org/plugins/debug-bar/
https://wordpress.org/plugins/monkeyman-rewrite-analyzer/
https://wordpress.org/plugins/wp-permastructure/

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

你很接近。您的重写规则使用了错误的查询变量,pagename 应该是公正的name.

这是一个新的4.4.1安装和216th主题的版本-

function bvt_product_init() {
    $args = array(
        \'label\'                 => __( \'Product\', \'domain\' ),
        \'description\'           => __( \'Company products\', \'domain\' ),
        \'supports\'              => array( \'title\', \'editor\', \'excerpt\', \'thumbnail\', \'revisions\', \'page-attributes\' ),
        \'taxonomies\'            => array( \'category\', \'post_tag\' ),
        \'hierarchical\'          => true,
        \'public\'                => true,
        \'show_ui\'               => true,
        \'show_in_menu\'          => true,
        \'menu_position\'         => 5,
        \'show_in_admin_bar\'     => true,
        \'show_in_nav_menus\'     => false,
        \'can_export\'            => true,
        \'has_archive\'           => true,
        \'rewrite\'               => array( \'slug\' => \'product\' ),
    );
    register_post_type( \'product\', $args );

    add_rewrite_rule( 
        \'^product/([^/]+)/?$\',
        \'index.php?post_type=product&name=$matches[1]\',
        \'top\'
    );
}
add_action( \'init\', \'bvt_product_init\' );

function bvt_product_flatten_hierarchies( $post_link, $post ) {
    if ( \'product\' != $post->post_type ) {
        return $post_link;
    }
    $uri = \'\';
    foreach ( $post->ancestors as $parent ) {
        $uri = get_post( $parent )->post_name . "/" . $uri;
    }
    return str_replace( $uri, \'\', $post_link );
}
add_filter( \'post_type_link\', \'bvt_product_flatten_hierarchies\', 10, 2 );
需要注意的一个潜在问题是,分级帖子类型允许您使用具有不同父级的相同slug创建帖子。这通常是可行的,因为它们是通过父/子路径查询的。如果URL结构中没有父/子关系,那么您可以创建一些帖子,如果slug与现有帖子匹配,则无法在前端查询这些帖子。只是要记住一些事。

相关推荐

Force pretty permalinks?

我正在构建一个插件,该插件将用于单个站点,并依赖于add_rewrite_rule 要工作,需要打开永久链接。打开它们并不困难,因为它只是一个站点,但我担心其中一个管理员可能会在不知道自己在做什么的情况下关闭它,并破坏该站点。如何以编程方式强制保持漂亮的永久链接?