如何设置不同自定义帖子类型之间的上下级关系

时间:2015-03-13 作者:Mattaton

我刚刚在帖子类型的“剧集”和帖子类型的“卡通系列”之间建立了帖子/家长关系

我使用这段代码添加到元框中,以从另一个帖子类型分配父级:

add_action(\'admin_menu\', function() {
    remove_meta_box(\'pageparentdiv\', \'episodes\', \'normal\');
});
add_action(\'add_meta_boxes\', function() {
    add_meta_box(\'episodes-parent\', \'Cartoon Series\', \'episodes_attributes_meta_box\', \'episodes\', \'side\', \'default\');
});

function episodes_attributes_meta_box($post) {
    $post_type_object = get_post_type_object($post->post_type);
    if ( $post_type_object->hierarchical ) {
        $pages = wp_dropdown_pages(array(\'post_type\' => \'cartoon-series\', \'selected\' => $post->post_parent, \'name\' => \'parent_id\', \'show_option_none\' => __(\'(no parent)\'), \'sort_column\'=> \'menu_order, post_title\', \'echo\' => 0));
        if ( ! empty($pages) ) {
            echo $pages;
        } // end empty pages check
    } // end hierarchical check.
}
这在管理屏幕上起到了作用,允许我将该系列设置为该集的父级,但当我尝试查看帖子时,我得到了404。url结构为:

domain/episodes/series-name/episode-name
该系列的url为:

domain/cartoon-series/series-name
我希望该集的url为:

domain/cartoon-series/series-name/episode-name
我错过了什么?是否可以将整个帖子类型设置为另一个帖子类型的子帖子类型?因此,我甚至可以得到剧集列表的url:

domain/cartoon-series/series-name/episodes
谢谢!马特

根据要求,以下是两种自定义职位类型的代码:

$labels = array(
    "name" => "Cartoon Series",
    "singular_name" => "Cartoon Series",
    "menu_name" => "Cartoon Series",
    "all_items" => "All Cartoon Series",
    "add_new" => "Add New",
    "add_new_item" => "Add New Cartoon Series",
    "edit" => "Edit",
    "edit_item" => "Edit Cartoon Series",
    "new_item" => "New Cartoon Series",
    "view" => "View",
    "view_item" => "View Cartoon Series",
    "search_items" => "Search Cartoon Series",
    "not_found" => "No Cartoon Series Found",
    "not_found_in_trash" => "No Cartoon Series Found in Trash",
    "parent" => "Parent Cartoon Series",
    );

$args = array(
    "labels" => $labels,
    "description" => "",
    "public" => true,
    "show_ui" => true,
    "has_archive" => true,
    "show_in_menu" => true,
    "exclude_from_search" => false,
    "capability_type" => "post",
    "map_meta_cap" => true,
    "hierarchical" => true,
    "rewrite" => array( "slug" => "cartoon-series", "with_front" => true ),
    "query_var" => true,
    "supports" => array( "title", "revisions", "thumbnail" ),           );
register_post_type( "cartoon-series", $args );

$labels = array(
    "name" => "Episodes",
    "singular_name" => "Episode",
    );

$args = array(
    "labels" => $labels,
    "description" => "",
    "public" => true,
    "show_ui" => true,
    "has_archive" => true,
    "show_in_menu" => true,
    "exclude_from_search" => false,
    "capability_type" => "post",
    "map_meta_cap" => true,
    "hierarchical" => true,
    "rewrite" => array( "slug" => "episodes", "with_front" => true ),
    "query_var" => true,
    "supports" => array( "title", "revisions", "thumbnail" ),           );
register_post_type( "episodes", $args );
我正在使用CPT UI插件,因此无法直接编辑该代码。这就是CPT UI提供的导出代码。

我没有任何其他代码链接这两个CPT。也许这就是我错过的。我刚刚在网上找到了一段代码,它将metabox放在页面上进行链接。做这项工作还不够吗?看起来它设置了post\\u父级。

谢谢马特

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

最后,我找到了一个有效的解决方案。卡通系列可以像你一样注册,但剧集自定义帖子类型不能是hirchical(我认为WordPress希望父内容与子内容的类型相同,如果使用post_parent 在里面wp_posts 数据库表)。

注册剧集时,重写规则必须设置为所需的slug,即cartoon-series/%series_name%. 然后我们可以筛选要替换的剧集链接%series_name% 具有父级的实际名称cartoon-series 帖子类型和重写规则,用于告诉WordPress何时需要卡通系列帖子类型,何时是剧集。

add_action(\'init\', function(){
    $labels = array(
        "name" => "Cartoon Series",
        "singular_name" => "Cartoon Series",
        "menu_name" => "Cartoon Series",
        "all_items" => "All Cartoon Series",
        "add_new" => "Add New",
        "add_new_item" => "Add New Cartoon Series",
        "edit" => "Edit",
        "edit_item" => "Edit Cartoon Series",
        "new_item" => "New Cartoon Series",
        "view" => "View",
        "view_item" => "View Cartoon Series",
        "search_items" => "Search Cartoon Series",
        "not_found" => "No Cartoon Series Found",
        "not_found_in_trash" => "No Cartoon Series Found in Trash",
        "parent" => "Parent Cartoon Series",
    );

    $args = array(
        "labels" => $labels,
         "description" => "",
        "public" => true,
        "show_ui" => true,
        "has_archive" => true,
        "show_in_menu" => true,
        "exclude_from_search" => false,
        "capability_type" => "post",
        "map_meta_cap" => true,
        "hierarchical" => true,
        "rewrite" => array( "slug" => "cartoon-series", "with_front" => true ),
        "query_var" => true,
        "supports" => array( "title", "revisions", "thumbnail" )
    );

    register_post_type( "cartoon-series", $args );

    $labels = array(
        "name" => "Episodes",
        "singular_name" => "Episode",
    );

    $args = array(
        "labels" => $labels,
        "description" => "",
        "public" => true,
        "show_ui" => true,
        "has_archive" => true,
        "show_in_menu" => true,
        "exclude_from_search" => false,
        "capability_type" => "post",
        "map_meta_cap" => true,
        "hierarchical" => false,
        "rewrite" => array( "slug" => "cartoon-series/%series_name%", "with_front" => true ),
        "query_var" => true,
        "supports" => array( "title", "revisions", "thumbnail" )
    );

    register_post_type( "episodes", $args );

});

add_action(\'add_meta_boxes\', function() {
    add_meta_box(\'episodes-parent\', \'Cartoon Series\', \'episodes_attributes_meta_box\', \'episodes\', \'side\', \'default\');
});

function episodes_attributes_meta_box($post) {
        $pages = wp_dropdown_pages(array(\'post_type\' => \'cartoon-series\', \'selected\' => $post->post_parent, \'name\' => \'parent_id\', \'show_option_none\' => __(\'(no parent)\'), \'sort_column\'=> \'menu_order, post_title\', \'echo\' => 0));
        if ( ! empty($pages) ) {
            echo $pages;
        } // end empty pages check
}

add_action( \'init\', function() {

    add_rewrite_rule( \'^cartoon-series/(.*)/([^/]+)/?$\',\'index.php?episodes=$matches[2]\',\'top\' );

});

add_filter( \'post_type_link\', function( $link, $post ) {
    if ( \'episodes\' == get_post_type( $post ) ) {
        //Lets go to get the parent cartoon-series name
        if( $post->post_parent ) {
            $parent = get_post( $post->post_parent );
            if( !empty($parent->post_name) ) {
                return str_replace( \'%series_name%\', $parent->post_name, $link );
            }
        } else {
            //This seems to not work. It is intented to build pretty permalinks
            //when episodes has not parent, but it seems that it would need
            //additional rewrite rules
            //return str_replace( \'/%series_name%\', \'\', $link );
        }

    }
    return $link;
}, 10, 2 );
NOTE: 请记住,在保存上述代码后,在尝试之前刷新重写规则。转到wp-admin/options-permalink.php 然后单击“保存”以重新定义重写规则。

NOTE 2: 可能需要添加更多的重写规则,例如用于分页帖子。此外,它可能需要更多的工作才能获得完整的解决方案,例如,在删除cartoon-series 是否也删除所有子集?在“管理编辑”屏幕中添加过滤器,以按后期家长筛选剧集?在管理编辑屏幕中修改剧集标题以显示父剧集名称?

SO网友:T.Todua

在这种情况下,无需硬编码,您只需使用此插件即可:

https://wordpress.org/plugins/add-hierarchy-parent-to-post/

您甚至可以从中获取代码。然而,这可能不是一个完整的解决方案。

SO网友:Mark Kaplun

您需要编写自己的URL解析代码,因为wordpress需要知道它试图根据URL结构从DB检索的帖子的类型,而您的URL结构没有给出任何提示。

这不是wordpress的重写规则API很容易做到的事情,但是没有任何东西可以阻止您绕过重写机制并自己解析URL。类似于1的东西。运行wordpress重新布线规则。如果找到内容,则显示并退出2。获取url的第一部分,检查是否有与该slug匹配的post类型3。对URL的其余部分进行循环,以验证帖子是否存在以及类型是否正确。如果所有内容都匹配,则显示最后找到的帖子,否则显示404页

结束

相关推荐

rewrite rules hierarchical

我希望我的WordPress遵循以下规则:/productes/ 包含所有产品的页面/productes/[category]/ 包含该类别所有产品的分类页面/productes/[category]/[subcategory]/ 包含该类别所有产品(与2相同)的分类页面/[productes]/[category]/[product]/ A.single-productes.php 将显示类别产品/[productes]/[category]/[subcategory]/[product]/ A.sin