Як встановити відносини батько-дитина між різними типовими повідомленнями


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.

У мене немає іншого коду, який би пов'язував два CPT. Можливо, саме цього мені не вистачає. Я щойно знайшов той код в Інтернеті, який розміщує метабокс на сторінці, щоб зробити посилання. Чи недостатньо, щоб виконати роботу? Схоже, він встановлює post_parent.

Дякую! Метт


Вибачте, але помилився. Відносини батько-дитина правильно встановлені. Мета-вікно не використовує мета-поле (саме це спочатку мене бентежило), воно використовує parent_idvar запитів, і для встановлення взаємозв'язку не потрібно більше кодувати. Проблема полягає в тому, що створена URL не розпізнається WordPress. Я намагався знайти правило переписати , щоб воно працювало, але я не мав успіху. Зараз я розслідую рішення.
cybmeta

Після деякого розслідування, я думаю, ви не можете змусити його працювати так, як вам хочеться. Зробити посаду батьком як батьків іншого типу публікації, здається, неможливо. Що ж, можливо, з вашим кодом такі відносини фактично встановлені, але бачити, як дочірній пост не працює у фронталі. Я спробував переписати правила і підключився, pre_get_postsщоб змінити запит без успіху, в чомусь складніше, що я не зміг зрозуміти. Як би мати кота бути батьком собаки. Я пропоную використовувати лише один ієрархічний тип публікації або встановити ритуалізацію, використовуючи метаполя .
cybmeta

Я думаю, що один тип хірархічного поста ідеально відповідає вашій ситуації.
cybmeta

2
Я справді намагаюся НЕ бути складним із цим. Якщо є більш елегантне рішення, я всі вуха. Я взагалі новачок у WP і до цього часу зробив досить добре, але цей мене наткнув. Як правило, я б просто зробив мультсеріал категорією і призначив його епізоду. Проблема полягає в тому, що у мене є й інші вкладені дані, крім епізодів, які підпадають під мультсеріал. Тож, схоже, мультсеріал також повинен бути КПТ. Це складно! :-D Чи можете ви пояснити мені, що ви маєте на увазі, використовуючи лише один ієрархічний тип повідомлення?
Маттатон

Відповіді:


9

Нарешті я знайшов робоче рішення. Мультяшної серії можуть бути зареєстровані , як ви робили , але епізоди призначені для користувача поштові типи не можуть бути hirarchical (я думаю , 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 );

ПРИМІТКА . Не забудьте очистити правила перезапису після збереження вищевказаного коду та перед тим, як спробувати. Перейдіть до wp-admin/options-permalink.phpта натисніть кнопку "Зберегти", щоб відновити правила перезапису.

ПРИМІТКА 2. Мабуть, потрібно додати більше правил перезапису, наприклад, щоб працювати для публікацій на сторінках. Також може знадобитися ще деяка робота, щоб мати повне рішення, наприклад, при видаленні cartoon-seriesвидалення також усіх дочірніх епізодів? Додати фільтр на екрані редагування адміністратора, щоб відфільтрувати епізоди по батькові? Змінити заголовок епізодів на екрані редагування адміністратора, щоб відобразити назву батьківського ряду?


Дякуємо, що вивчили це! Здається, що опублікований вами код викидає назву мультсеріалу з URL-адреси. Замість заміни% series_name% на ім'я епізоду,% series_name% має бути іменем батьків епізоду. Назва епізоду буде після цього. Чомусь у полі мультфільму серія не заповнюється, щоб вибрати батьків. Тому я вважав, що епізоди повинні бути ієрархічними. Намагаюся розібратися, чому.
Маттатон

Так, епізоди повинні бути ієрархічними, щоб мета-поле мультсеріалу було заповнено.
Маттатон

З ієрархічними епізодами, щоб я міг встановити батьків, URL просто погіршився. За допомогою слизи, як ви запропонували, я отримую назву серії в URL-адресі двічі. Отже, замість того, domain/episodes/series-name/episode-nameяк раніше, я отримавdomain/episodes/series-name/series-name/episode-name
Маттатон

Як я вже сказав, епізоди не можуть бути ієрархічними. Я змінив код мета-коду для заповнення неієрархічними типами публікацій. Використовуйте точний код, який я розмістив, я перевірив його і він працює. Якщо ви використовуєте інший код, я не можу знати, що не так. Просто скопіюйте та вставте код з відповіді та протестуйте його. Вам може знадобитися відключити плагін CPT UI або, принаймні, видалити користувацькі типи публікацій із плагіна, оскільки вони зареєстровані в коді.
cybmeta

Ах, вибачте, я швидко просканував і подумав, що частина така сама. Ви маєте рацію, сторінка завантажується зараз, і URL виглядає правильним.
Маттатон


-1

Для цього вам потрібно буде написати свій власний код розбору URL-адреси, оскільки wordpress повинен знати тип публікації, яку він намагається отримати з БД на основі структури URL-адреси, і ваша структура URL-адреси не дає на це жодних підказів.

Це не те, що дуже легко зробити за допомогою API правил перезапису Wordpress, але немає нічого, що заважає вам обійти механізм перезапису та розібрати URL-адреси самостійно. Щось на кшталт 1. запустіть wordpress rewite правила. Якщо вміст був знайдений, виведіть його та вийдіть із нього 2. Отримайте першу частину URL-адреси, перевірте, чи є повідомлення, яке відповідає цій службі та очікуваному типу публікації типу 3. у правильному типі. 4. якщо все відповідає відображенню останнього знайденого допису, інакше відобразити сторінку 404

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.