Вкладені спеціальні типи публікацій з постійними посиланнями


9

Я намагаюся створити багаторівневу структуру типу користувальницької пошти з постійними посиланнями, схожими на них authors/books/chapters, з авторами, книгами та розділами, створеними як власний тип публікації. Наприклад, може виглядати типова URL-адреса на цьому веб-сайтіexample.com/authors/stephen-king/the-shining/chapter-3/

Кожна глава може належати лише одній книзі, а кожна книга може належати лише одному автору. Я розглядав можливість використання таксономій замість CPT для авторів і книг, але мені потрібно пов’язати метадані з кожним елементом, і для цього я віддаю перевагу інтерфейсу публікації.

Я більшу частину шляху там, просто налаштувавши кожну власну публікацію як дочірню запис в CPT на один рівень вище. Наприклад, я створюю "Главу 3" і призначаю "Сяючий" як батьків, використовуючи власну метаполе. "Сяючий" у свою чергу має "Стівена Кінга" як батька. У мене не було проблем із створенням цих відносин.

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

Ось скріншот мого аналізатора переписування.

Ось як я зареєстрував свої CPT:

function cpt_init() {

  $labels = array(
    'name' => 'Authors'
   );

  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => array(
        'slug' => 'author',
        'with_front' => FALSE,
    ),
    'with_front' => false,
    'capability_type' => 'post',
    'has_archive' => false, 
    'hierarchical' => true,
    'menu_position' => null,
    'supports' => array( 'title', 'editor' )
  ); 

  register_post_type('authors',$args);

  $labels = array(
    'name' => 'Books'
  );

  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => array(
        'slug' => 'author/%authors%',
        'with_front' => FALSE,
    ),
    'with_front' => false,
    'capability_type' => 'post',
    'has_archive' => false, 
    'hierarchical' => true,
    'menu_position' => null,
    'supports' => array( 'title', 'editor' )
  ); 

  register_post_type('books',$args);


  $labels = array(
    'name' => 'Chapters'
   );

  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => array(
        'slug' => 'author/%authors%/%books%',
        'with_front' => FALSE,
    ),
    'with_front' => FALSE,
    'capability_type' => 'post',
    'has_archive' => false, 
    'hierarchical' => true,
    'menu_position' => null,
    'supports' => array( 'title', 'editor' )
  ); 

  register_post_type('chapters',$args);

}

add_action( 'init', 'cpt_init' );

То чи є спосіб змінити пріоритет моїх правил переписування, щоб усі автори, книги та глави були зіставлені першими?

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


Чи вважали ви просто використовувати Сторінки? Ви отримаєте правильну структуру постійної посилання автоматично.
Майкл Хемптон

Я це точно вважав. Проблема сторінок полягає в тому, що у нас може бути 100 предметів онуків для одного автора, якими в адміністраторі сторінок буде дуже важко керувати. Також нам потрібно мати можливість запиту за типом пошти.
Далтон

Я працюю над рішенням, але у мене є швидке запитання: чи ключовим є "автор" перед кожною постійною посиланням? Тому що це, здається, налепиться. Я думаю, що це занадто сильно плутає WordPress, тим більше, що це постійна поштова скринька, яка також використовується для сторінок авторів WP. Якщо потрібен "автор", я думаю, що все це все ще можливо зробити ... це буде просто складніше.
Рейчел Карден

На жаль, я не здогадувався, що автор збирається вступати в конфлікт із вбудованим авторським службовцем WP. Ні, цього не потрібно, це може бути все що завгодно. Я припускав, що мені щось там потрібно, тому що це CPT, але це так само легко може бути "письменниками" чи будь-чим іншим.
Далтон

Я зрозумів, що плутанина насправді полягає в тому, що CPT поділяє "автора" як базового слима. Після того, як ви встановите "автор" як слуп для "авторів" CPT, а потім ви встановите "автор /% автор%" для CPT "книг" і "автор /% автор% /% книга%" для CPT " ', то WordPress вважає, що дописи для' книг ', а повідомлення для' глав 'є буквально ієрархічними дитячими повідомленнями для' авторів '. Чи має це сенс? У моєму тестуванні ви могли б зберегти "автора" як основу для авторів CPT, і це працює чудово. Тож замініть моє попереднє запитання на: чи потрібен вам "автор", чи може слиз починати з% author%?
Рейчел Карден

Відповіді:


11

Якщо ви хочете зберегти «автор» в якості базового слимака в постійних посиланнях, тобто example.com/authors/stephen-king/ для СРТ "авторів, example.com/authors/stephen-king/the-shining/ для "Книги" CPT та example.com/authors/stephen-king/the-shining/chapter-3/ для "глав" CPT, WordPress вважатиме, що майже все - це "авторський пост" або ієрархічна дитина автора 'пост і, оскільки це не так, WordPress в кінцевому підсумку дуже заплутаний.

З урахуванням сказаного, існує вирішення, яке є досить базовим, але поки ваша структура постійної посилання завжди дотримується того самого порядку, тобто за словом "автори" завжди слідує авторський слизь, за яким завжди слідує книжковий кулик, який завжди дотримується за главою слима, то вам слід добре піти.

У цьому рішенні немає необхідності визначати переписувати слизьку у визначеному користувальницькому визначенні типу "для глав" і "книг", але встановити "авторів" переписати слизьку просто як "авторів", помістіть у своїх функціях наступний код .php Запишіть і "очистіть" свої правила перезапису.

add_action( 'init', 'my_website_add_rewrite_tag' );
function my_website_add_rewrite_tag() {
    // defines the rewrite structure for 'chapters', needs to go first because the structure is longer
    // says that if the URL matches this rule, then it should display the 'chapters' post whose post name matches the last slug set
    add_rewrite_rule( '^authors/([^/]*)/([^/]*)/([^/]*)/?','index.php?chapters=$matches[3]','top' );
    // defines the rewrite structure for 'books'
    // says that if the URL matches this rule, then it should display the 'books' post whose post name matches the last slug set
    add_rewrite_rule( '^authors/([^/]*)/([^/]*)/?','index.php?books=$matches[2]','top' );   
}

// this filter runs whenever WordPress requests a post permalink, i.e. get_permalink(), etc.
// we will return our custom permalink for 'books' and 'chapters'. 'authors' is already good to go since we defined its rewrite slug in the CPT definition.
add_filter( 'post_type_link', 'my_website_filter_post_type_link', 1, 4 );
function my_website_filter_post_type_link( $post_link, $post, $leavename, $sample ) {
    switch( $post->post_type ) {

        case 'books':

            // I spoke with Dalton and he is using the CPT-onomies plugin to relate his custom post types so for this example, we are retrieving CPT-onomy information. this code can obviously be tweaked with whatever it takes to retrieve the desired information.
            // we need to find the author the book belongs to. using array_shift() makes sure only one author is allowed
            if ( $author = array_shift( wp_get_object_terms( $post->ID, 'authors' ) ) ) {
                if ( isset( $author->slug ) ) {
                    // create the new permalink
                    $post_link = home_url( user_trailingslashit( 'authors/' . $author->slug . '/' . $post->post_name ) );
                }
            }

            break;

        case 'chapters':

            // I spoke with Dalton and he is using the CPT-onomies plugin to relate his custom post types so for this example, we are retrieving CPT-onomy information. this code can obviously be tweaked with whatever it takes to retrieve the desired information.
            // we need to find the book it belongs to. using array_shift() makes sure only one book is allowed
            if ( $book = array_shift( wp_get_object_terms( $post->ID, 'books' ) ) ) {

                // now to find the author the book belongs to. using array_shift() makes sure only one author is allowed
                $author = array_shift( wp_get_object_terms( $book->term_id, 'authors' ) );

                if ( isset( $book->slug ) && $author && isset( $author->slug ) ) {
                    // create the new permalink
                    $post_link = home_url( user_trailingslashit( 'authors/' . $author->slug . '/' . $book->slug . '/' . $post->post_name ) );
                }

            }

            break;

    }
    return $post_link;
}

Дізнайтеся більше про плагін CPT-onomies


Це прекрасно працює, дякую! Я відчуваю, що я просто так багато навчився. Плагін CPT-onomies теж дуже цікавий. wordpress.org/extend/plugins/cpt-onomies
Далтон

У мене є відчуття, що ви можете зіткнутися з деякими перешкодами, коли ваша "бібліотека" зростає, але я вже маю на увазі якийсь код, тому, якщо ви це зробите, просто дайте мені знати.
Рейчел Карден

@RachelCarden Що ви робите, коли дві книги мають одну назву, але різні автори? У зібраній URL-адресі відбудеться зіткнення! Як ти це вирішуєш?
Segfault

1
@Segfault Вам доведеться завантажити всі авторські слизи, щоб ви могли їх жорстко зашифрувати в правила переписування: foreach ($ author_slugs як $ author_slug) {add_rewrite_rule ('^ автори /'. $ Author_slug. '/ ([ ^ /] *) / ([^ /] *) /? ',' index.php? автори = '. $ author_slug.' & chapters = $ match [2] ',' top '); add_rewrite_rule ('^ автори /'. $ author_slug. '/( evidence^/Sense*)/?','index.php?authors='. $ author_slug. '& books = $ match [1]', 'top') ; }
Рейчел Карден

@Segfault Ви можете використовувати get_terms () , якщо ви використовуєте CPT-ономію, або get_posts () для отримання назв публікацій / службовців.
Рейчел Карден

4

Я не маю особистого досвіду з подібним сценарієм, але Ренді Хойт зробив презентацію в WordCamp San Fran минулих вихідних про "Типи підпорядкованих повідомлень", які звучать як те, про що ви говорите.

Ось його сторінка для бесіди, яка включає слайди презентації та посилання на плагін, який він створив для роботи з підлеглими типами публікацій: http://randyhoyt.com/wordpress/subordinate-post-types/


Дякую, це виглядає як непоганий ресурс. Не зрозуміло, чи підтримує це стосунки онуків (хоча це не здається в моєму тестуванні), і це насправді не допомагає з постійними посиланнями. Я вже придумав спосіб налагодити стосунки між дитиною та батьком (хоча це досить приємний спосіб зробити це), але постійні посилання - це справді проблема, на якій я зараз застряг.
Далтон

1

Правила будуть додані до extra_rules_top WP_Rewrite у порядку, що додаються додаткові permastructs. Отже, перемикаючи порядок реєстрації типів публікацій, буде переключено порядок створення правил перезапису, змушуючи спочатку переписати розділ, щоб вони були зіставлені спочатку. Однак, оскільки ви використовуєте query_var з інших post_types, wp_query може в кінцевому підсумку відповідати одному з таких, як ім'я запиту, перш ніж відповідати главі, як вам потрібно.

Я б створив нові теги для перезапису, щоб представити заповнювачі батьківського автора та батьківської книги, тобто:

add_rewrite_tag('%parent-book%', '([^/]+)', 'parent_book=');

Роблячи це, вам доведеться відфільтрувати "query_vars", щоб зробити "parent_book" загальнодоступним. Тоді вам потрібно буде додати фільтр до pre_get_posts, який перетворить набір імен як запит_var на батьківську книгу в post_id і встановить його як "post_parent".


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