web-dev-qa-db-ja.com

異なるカスタム投稿タイプ間で親子関係を設定する方法

投稿タイプ「エピソード」と投稿タイプ「漫画シリーズ」の間に、投稿/親の関係を設定しました。

このコードを使用して、メタボックスに追加して別の投稿タイプの親を割り当てます。

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

ありがとうございます。マット


ご要望に応じて、問題の2つのカスタム投稿タイプのコードを次に示します。

$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が提供するエクスポートコードです。

この2つのCPTを結び付ける他のコードはありません。たぶんそれは私が欠けているものです。リンクを行うためにメタボックスをページに配置するコードをオンラインで見つけたところです。仕事をするのに十分ではありませんか? post_parentが設定されているようです。

ありがとうございます。マット

12
Mattaton

ついに私は実用的な解決策を見つけました。漫画シリーズはあなたがしたように登録することができますが、エピソードカスタム投稿タイプは階層的にすることはできません(WordPressはpost_parentデータベーステーブルでwp_postsを使って設定された親コンテンツは子コンテンツと同じタイプであると思います)。

エピソードを登録するときは、書き換え規則を必要なスラッグ、つまり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を削除すると、すべての子エピソードも削除されます。投稿の親によってエピソードをフィルタリングするために管理者編集画面でフィルタを追加しますか?親シリーズ名を表示するには、管理編集画面でエピソードのタイトルを変更しますか?

9
cybmeta

この場合、ハードコーディングは必要ありません...このプラグインを使用するだけです。

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

あなたもそれからコードをつかむことができます。しかし、それは完全な解決策ではないかもしれません。

1
T.Todua