Налаштування ієрархічного користувацького типу публікації постійних посилань працювати так само, як сторінки


16

Тут я переглянув кожне запитання про користувацькі постійні посилання типу публікацій, але, здається, це проблеми або з переписаними користувальницькими таксономіями, або явна відсутність flush_rewrite_rules (). Але в моєму випадку я використовую лише спеціальний тип публікації (без систематики), встановлений як ієрархічний (тому я можу призначити відносини батько-дитина), з належною "підтримкою" метабокса атрибутів тощо, тощо. I Ви переписали правила переписання тисячі різних способів. Я пробував різні структури постійної посилання. Але дочірні URL-адреси завжди призводять до 404!

Спочатку у мене були незалежні спеціальні типи публікацій для елементів "батьків" та "дочірній" (використовуючи p2p), і, напевно, не виникло б проблем із використанням таксономії для "батьківського" групування - я знаю, що це було б семантично більш точним. Але для клієнта їм найпростіше візуалізувати ієрархію, коли "повідомлення" відображаються в адміністраторі так само, як і сторінки: просте дерево, де діти з’являються під батьківським, з префіксом "-" і в належний порядок. Також можна використовувати різні способи призначення замовлення через перетягування n-drop. Групування за допомогою таксономії (або p2p) призводить до плоского списку "постів" у списках адміністратора, що просто не так візуально очевидно.

Тож те, про що я хочу, - це буквально та сама поведінка, що і основні "сторінки", але з моїм користувацьким типом публікації. Я зареєстрував тип публікації так, як очікувалося, і в адміністраторі він працює відмінно - я можу призначити батьківський і меню_порядку для кожного "повідомлення" бюлетеня, вони відображаються правильно у списках редагування:

Spring 2012
 First Article
 Second Article

І їхні постійні посилання, здається, сконструйовані належним чином. Насправді, якщо я що-небудь змінив про структуру або навіть змінив кулю переписати, зареєструвавши тип публікації, вони автоматично оновлюються правильно, тому я знаю, що щось працює:

http://mysite.com/parent-page/child-page/                  /* works for pages! */
http://mysite.com/post-type/parent-post/child-post/        /* should work? */
http://mysite.com/newsletter/spring-2012/                  /* works! */
http://mysite.com/newsletter/spring-2012/first-article/    /* 404 */
http://mysite.com/newsletter/spring-2012/second-article/   /* 404 */

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

Моя структура постійної посилання встановлена ​​на:

http://mysite.com/%postname%/

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

http://mysite.com/%category%/%postname%/

Аргументи CPT мого реєстру включають:

$args = array(
    'public'                => true,
    'publicly_queryable'    => true,
    'show_ui'               => true,
    'has_archive'           => 'newsletter',
    'hierarchical'          => true,
    'query_var'             => true,
    'supports'              => array( 'title', 'editor', 'thumbnail', 'page-attributes' ),
    'rewrite'               => array( 'slug' => 'newsletter', 'with_front' => false ),

Єдина видима різниця між моїми спеціальними дітьми типу публікації та звичайною сторінкою дітьми - це те, що мій CPT має шлака на початку структури постійної посилання, а потім слідує за батьківським / дочірнім слизьком (де сторінки починаються лише з батьків / дочірніх слимаків, немає "префікса"). Чому це збило б речі, я не знаю. Дуже багато статей вказують на те, що саме так повинні поводитися такі ієрархічні постійні посилання CPT - але мої, хоч і добре сформовані, не працюють.

Що також мене бентежить, коли я вивчаю запити_варів для цієї сторінки 404 - вони, здається, містять правильні значення для WP, щоб "знайти" мої дочірні сторінки, але щось не працює.

$wp_query object WP_Query {46}
public query_vars -> array (58)
'page' => integer 0
'newsletter' => string(25) "spring-2012/first-article"
'post_type' => string(10) "newsletter"
'name' => string(13) "first-article"
'error' => string(0) ""
'm' => integer 0
'p' => integer 0
'post_parent' => string(0) ""
'subpost' => string(0) ""
'subpost_id' => string(0) ""
'attachment' => string(0) ""
'attachment_id' => integer 0
'static' => string(0) ""
'pagename' => string(13) "first-article"
'page_id' => integer 0
[...]

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

Використовуючи Інспектор правил перезапису, це відображається для URL-адреси: http://mysite.com/newsletter/spring-2012/first-article/

newsletter/(.+?)(/[0-9]+)?/?$   
       newsletter: spring-2012/first-article
           page: 
(.?.+?)(/[0-9]+)?/?$    
       pagename: newsletter/spring-2012/first-article
           page: 

як відображається на іншій сторінці інспектора:

RULE:
newsletter/(.+?)(/[0-9]+)?/?$
REWRITE:
index.php?newsletter=$matches[1]&page=$matches[2]
SOURCE:
newsletter

Цей результат перезапису наштовхне мене на думку, що наступна "не дуже" постійна посилання спрацює:

http://mysite.com/?newsletter=spring-2012&page=first-article

Це не 404, але він показує батьківський пункт CPT "бюлетень", а не дочірню. Запит виглядає так:

Array
(
    [page] => first-article
    [newsletter] => spring-2012
    [post_type] => newsletter
    [name] => spring-2012
)

Відповіді:


15

Я вперше беру участь тут на біржі стеків, але я підкажу, і я можу допомогти вам направити вас у правильному напрямку.

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

Ці аргументи реєстрації CPT виглядають чудово, але коли запитується CPT, pagenamevar запиту не повинен мати значення, а nameзміна запиту повинна бути такою ж, як і newsletterтут, тому виявляється, що десь у вашому налаштуванні є конфлікт.

Щоб налагодити налагодження, встановіть та активуйте плагін інспектора правил перезапису , а потім перейдіть на екран у розділі " Інструменти -> Переписати правила ".

  1. Переглядаючи список, усі ваші правила для бюлетеня CPT повинні бути перелічені перед будь-якими правилами перезапису сторінки. Перевірте, чи це так, скануючи стовпець " Джерело ".
  2. Якщо це перевіряється, введіть URL-адресу для CPT "першої статті" в полі " Відповідна URL-адреса " та натисніть кнопку "Фільтр", щоб побачити, яке правило відповідає. Він повинен відповідати правилам розсилки та правилам сторінки, але перше правило повинно бути першим.

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

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

add_filter( 'request', 'se77513_display_query_vars', 1 );

function se77513_display_query_vars( $query_vars ) {
    echo '<pre>' . print_r( $query_vars, true ) . '</pre>';

    return $query_vars;
}

Будь-які плагіни / функції, що змінюють параметри запитів, можуть спричинити конфлікт, тому відключіть їх, якщо ви все ще бачите проблеми. Також вимийте правила перезапису після кожного кроку, особливо якщо запит відповідав неправильному правилу на другому кроці вище (тримайте екран "Постійні посилання" відкритим на окремій вкладці та просто оновіть його).


Я відредагував питання, щоб показати висновок інспектора правил перезапису правил, оскільки ці коментарі не дозволяють достатнього форматування. Правила CPT відображаються вгорі списку, перш ніж будь-що інше, але не впевнені, які з наведених нижче правил є "сторінками" (не зрозуміло). Крім того, жодних зіткнень у post_nameколонці немає.
соматично

чи маєте ви думки щодо належної структури постійної посилання? Я повернувся до /%postname%/тих пір, оскільки включаючи /%category%/лише, здається, ще більше плутаю речі в інспекторі переписування. Я навіть бачив, як люди стверджують, що /%category%/магічно відображено для CPT означає "батьків", хоча я не вважаю це правдою.
соматично

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

Що стосується структури постійної посилання, я не прихильник включати категорію. Це просто ще одна рухома частина, яка нічого не допомагає, і публікації можуть належати до кількох категорій. Якщо взагалі є якийсь шанс, що ви можете змінити структуру постійної посилання в майбутньому або хочете, щоб інший CPT завантажувався без приставки слугу, я рекомендую "простір імен" вашої структури чимось виправленим і унікальним, як /blog/%postname%/.
Брейді Верхер

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

5

parent/ChildПостійне посилання Працює з коробки до тих пір , як ви встановите

'hierarchical'=> true,
'supports' => array('page-attributes' ....

Оновлення:

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

add_action('init','test_post_type_wpa77513');
function test_post_type_wpa77513(){
    $args = array(
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true, 
        'show_in_menu' => true, 
        'query_var' => true,
        'rewrite' => true,
        'capability_type' => 'post',
        'has_archive' => true, 
        'hierarchical' => true,
        'supports' => array( 'title', 'editor', 'thumbnail', 'page-attributes' )
    ); 

    register_post_type( 'newsletter', $args );
}

і постійна посилання налаштована на те, щоб /%postname%/я отримував бюлетень / батька / дитини працював чудово.


мій код вище не показував його, але я маю page-attributesв підтримках (що насправді стосується лише показу метабокса для призначення батьків, не повинно впливати на постійні посилання) - але отримання 404-х. Яку структуру постійної посилання потрібно встановити? чи це має значення?
соматично

@somatic я щойно перевірив це знову, і він справно працює, так як за постійною посиланням я не впевнений, чи має це значення, але будь-яким чином я оновив свою відповідь.
Бейнтернет

Я можу підтвердити, що, додавши масив аргументів для 'міток' (без якого CPT не з’явиться в адміністраторі), цей базовий приклад працює на ванільній установці WP3.5 з twentytwelve. Але я помічаю кілька ключових відмінностей у ваших register_post_type$ аргументах: я використовував 'rewrite' => array( 'slug' => 'newsletter', 'with_front' => false ), де ви просто використовували true. Крім того, просто пройшов trueдля has_archive, де я пройшов слимак. Однак, коли я зіставив ваші аргументи, у мене все-таки було 404 ... Ще намагаюся простежити, де я помиляюся.
соматично

3

Крім запитання "Чи намагалися ви вимкнути і знову ввімкнути?" , Я також повинен запитати "Чи є у вас активні плагіни і ваша тема робить щось із постійними посиланнями (наприклад: реєстрація таксономії, типи публікацій, додавання правил перезапису" тощо)?

Якщо так: Чи все-таки це відбувається після того, як ви відключили всі плагіни та перейшли на TwentyEleven? введіть тут опис зображення

Для подальшої налагодження перейдіть до GitHub і захопіть плагін Toschos "Переписати" . Потім перейдіть до офіційного репорта модуля на wp.org і візьміть плагін MonkeyManRewriteAnalyzer . Я навіть написав невелике розширення, щоб склеїти обидва разом. Це дасть вам багато деталей щодо налаштування.


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

@somatic Звичайно, не відключаючи своїх :)
кайзер

@somatic Дивіться оновлення.
кайзер

1

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

Тож мені залишилося завдання вручну відключити / включити кожен з 9 великих класів, а потім, виявивши щонайменше 2 з них викликати 404, переходити кожну функцію по одній і відключати / вмикати їх, а потім простежувати лінію по лінії в межах цих функцій - груба спроба зрозуміти, що саме спричиняє 404, навіть якщо я не знав чому.

Ось тоді я виявив наслідки використання $query->get_queried_object(). Здавалося б, використання цієї функції обгортки насправді змінює сам $-запит, який я вважав, що повертаюсь незмінним наприкінці своєї функції. Три фільтра через 2 класу були залучені , що модифікований запит: parse_query, posts_orderby, posts_join- і всі функції зворотного виклику були виклику $query->get_queried_object()на пройдений $queryарг , щоб потім запустити кілька умовних тестів , а іноді і змінити запит вари (наприклад , для особливих випадків порядку сортування). Як не дивно, ці функції насправді добре працювали на те, що вони були розроблені, незважаючи на моє використання функції. Я ніколи не помічав нічого поганого з поверненим $ запитом раніше!

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

Зізнаюсь, я досі не знаю, чому саме виклик цієї функції порушує саме цей невеликий аспект дочірніх сторінок CPT - і все ж ніколи не проявляв жодних інших проблем! Але було зрозуміло, що використовуючи його в зворотному режимі зворотного виклику фільтрів, $queryякимось чином керував поверненим . Видаливши цей виклик, мої 404 помилки зникли.

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

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


Ви також можете використовувати функцію обгортки, get_queried_object()не перехоплюючи $wpdbоб'єкт.
кайзер

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

Я просто спробував використовувати обгортку всередині мого фільтра parse_query. Це знову спричинило ті самі 404 помилки. Я повинен знайти якийсь спосіб повторити те, що можна зробити, get_queried_object()не забруднивши ці фільтри ...
соматично

-2

У вас працює остання версія WP? Я думаю, що це перше питання (наприклад, коли ви телефонуєте в службу технічної підтримки, і вони запитують вас, чи ваш комп'ютер підключений!), Оскільки я прочитав, що ця проблема була вирішена в самій останній версії оновлення версії.

На сайті digwp.com є публікація, яка вирішує цю проблему (http://digwp.com/2011/06/dont-use-postname/). Мабуть, WP не може легко визначити різницю між публікаціями та сторінками, і якщо ви запускаєте URL-адреси за допомогою текстового параметра, WP запускає прапор, який створює правило для кожної вашої сторінки / публікації. Якщо на вашому сайті багато вмісту, це може призвести до величезної кількості запитів, і ваш сервер, ймовірно, вичерпається, що призведе до купки 404, навіть якщо сторінки там є.

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


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