다른 사용자 정의 게시물 유형간에 상위-하위 관계를 설정하는 방법


14

게시물 유형 "에피소드"와 게시물 유형 "만화 시리즈"사이에 게시물 / 부모 관계를 설정했습니다.

이 코드를 사용하여 메타 상자에 추가하여 다른 게시물 유형의 부모를 할당했습니다.

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를 연결하는 다른 코드가 없습니다. 어쩌면 내가 놓친 것일 수도 있습니다. 방금 링크를 수행하기 위해 메타 박스를 페이지에 배치하는 코드를 온라인에서 발견했습니다. 일을하기에 충분하지 않습니까? post_parent를 설정 한 것 같습니다.

감사! 매트


죄송하지만 잘못되었습니다. 부모-자식 관계가 올바르게 설정되었습니다. 메타 박스는 메타 필드를 사용하지 않고 있습니다 (처음에 혼란 스러웠습니다) parent_id.query var를 사용하며 관계를 설정하기 위해 더 코딩 할 필요가 없습니다. 문제는 생성 된 URL이 WordPress에서 인식되지 않는다는 것입니다. 나는 그것을 작동 시키는 다시 쓰기 규칙 을 찾으려고 노력 했지만 성공하지 못했습니다. 이제 솔루션을 조사하고 있습니다.
cybmeta

조사가 끝나면 원하는 방식으로 작동시킬 수 없다고 생각합니다. 다른 게시물 유형의 상위 항목으로 게시물 유형을 갖는 것은 불가능합니다. 글쎄, 당신의 코드를 사용하면 관계가 실제로 설정되어 있지만 자식 게시물을 보는 것이 프런트 엔드에서 작동하지 않는 것이 가능합니다. 나는 규칙을 다시 작성하고 pre_get_posts성공하지 않고 쿼리를 변경 하려고 시도했지만 이해하지 못한 더 복잡한 것이 포함되어 있습니다. 고양이를 강아지의 부모로 삼는 것과 같습니다. 하나의 계층 적 게시물 유형 만 사용하거나 메타 필드를 사용하여 영역을 설정하는 것이 좋습니다 .
cybmeta

하나의 계층 적 게시물 유형이 귀하의 상황에 완벽하게 부합한다고 생각합니다.
cybmeta

2
나는 정말로 이것으로 복잡하지 않도록 노력하고 있습니다. 더 우아한 솔루션을 사용할 수 있다면 나는 모두 귀입니다. 나는 일반적으로 WP를 처음 접했고 지금까지 꽤 잘 해왔지만 이것은 나를 혼란스럽게했다. 일반적으로 만화 시리즈를 범주로 만들고 에피소드에 할당합니다. 문제는 또한 만화 시리즈 아래에 에피소드가 아닌 다른 중첩 데이터가 있다는 것입니다. 따라서 만화 시리즈는 CPT 여야 할 것 같습니다. 복잡합니다! :-D 하나의 계층 적 게시물 유형 만 사용하여 의미하는 바를 설명해 주시겠습니까?
Mattaton

답변:


9

마지막으로 작동하는 솔루션을 찾았습니다. 만화 시리즈는 당신이했던 것처럼 등록 할 수 있지만 에피소드 사용자 정의 게시물 유형은 계층적일 수 없습니다 ( 데이터베이스 테이블 post_parent에서 관계를 설정하면 WordPress는 부모 콘텐츠가 자식 콘텐츠와 동일한 유형이라고 생각 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 );

참고 : 위 코드를 저장 한 후 시도하기 전에 다시 쓰기 규칙을 플러시해야합니다. wp-admin/options-permalink.php다시 쓰기 규칙을 다시 작성하려면 저장으로 이동하여 클릭하십시오.

참고 2 : 페이지 매김 게시물에 대한 작업과 같이 더 많은 다시 쓰기 규칙을 추가해야 할 수도 있습니다. 또한 cartoon-series모든 자식 에피소드를 삭제하는 경우와 같이 완전한 솔루션을 얻으려면 더 많은 작업이 필요할 수 있습니까? 게시물 편집을 통해 에피소드를 필터링하려면 관리자 수정 화면에 필터를 추가 하시겠습니까? 부모 시리즈 이름을 표시하도록 관리자 편집 화면에서 에피소드 제목을 수정 하시겠습니까?


이것을 조사해 주셔서 감사합니다! 귀하가 게시 한 코드가 URL에서 만화 시리즈의 이름을 삭제하는 것 같습니다. % series_name %을 에피소드 이름으로 바꾸는 대신 % series_name %은 에피소드의 상위 이름이어야합니다. 에피소드 이름은 그 이후에있을 것입니다. 어떤 이유로, 부모를 선택하기 위해 만화 시리즈 상자가 채워지지 않습니다. 그래서 에피소드는 계층 적이어야한다고 생각했습니다. 이유를 알아 내려고 노력 중입니다.
Mattaton

예, 카툰 시리즈 메타 박스를 채우려면 에피소드가 계층 적이어야합니다.
Mattaton

에피소드가 계층 구조이므로 부모를 설정할 수 있으므로 URL이 더 나빠졌습니다. 제안한대로 슬러그를 사용하면 URL에 시리즈 이름이 두 번 나타납니다. 그래서, domain/episodes/series-name/episode-name전처럼 대신에domain/episodes/series-name/series-name/episode-name
Mattaton

내가 말했듯이 에피소드는 계층적일 수 없습니다. 비 계층 적 게시물 유형으로 채워지도록 메타 박스 코드를 수정했습니다. 내가 게시 한 정확한 코드를 사용하고 테스트 한 결과 작동합니다. 다른 코드를 사용하면 무엇이 잘못되었는지 알 수 없습니다. 답변에서 코드를 복사하여 붙여 넣고 테스트하십시오. CPT UI 플러그인을 비활성화하거나 최소한 코드에 등록 된 플러그인에서 사용자 정의 게시물 유형을 삭제해야 할 수도 있습니다.
cybmeta

아 죄송합니다. 저는 빠르게 스캔을했고 그 부분이 같다고 생각했습니다. 당신이 맞아요, 페이지가 지금로드되고 URL이 올바르게 보입니다.
Mattaton


-1

워드 프레스가 URL 구조를 기반으로 DB에서 검색하려는 게시물의 유형을 알아야하므로 URL 구조는 이에 대한 힌트를 제공하지 않으므로 자체 URL 구문 분석 코드를 작성해야합니다.

이것은 워드 프레스의 다시 쓰기 규칙 API로 수행하기가 쉽지 않지만 다시 쓰기 메커니즘을 무시하고 URL을 직접 구문 분석하는 것을 막을 수있는 것은 없습니다. 1. wordpress rewite 규칙을 실행하십시오. 내용이 발견되면 그것을 표시하고 2를 종료하십시오. URL의 첫 번째 부분을 가져 와서 예상 게시물 유형 3과 슬러그와 일치하는 게시물이 있는지 확인하십시오. 올바른 유형으로. 4. 모든 항목이 마지막으로 찾은 게시물을 표시하면 404 페이지를 표시합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.