Я перебрал каждый вопрос здесь о пользовательских постоянных типах записей, но в большинстве случаев это либо проблемы с пользовательскими изменениями таксономии, либо очевидное отсутствие flush_rewrite_rules (). Но в моем случае я использую только пользовательский тип записи (без таксономии), установленный как иерархический (чтобы я мог назначать отношения родитель-потомок), с надлежащей «поддержкой» для атрибута metabox и т. Д. И т. Д. Переписал правила тысячами разных способов. Я пробовал разные постоянные структуры. Но дочерние URL всегда приводят к 404!
Первоначально у меня были независимые пользовательские типы записей для «родительских» и «дочерних» элементов (с использованием p2p), и у меня, вероятно, не было бы проблем с использованием таксономии для «родительской» группировки - я знаю, что они были бы семантически более точными. Но для клиента им проще всего представить иерархию, когда «сообщения» отображаются в админке так же, как страницы: простое дерево, в котором дочерние элементы отображаются под родительским элементом с префиксом «-» и в правильный порядок. Также могут быть использованы различные методы для назначения порядка с помощью drag-n-drop. Группировка через таксономию (или p2p) приводит к простому списку «постов» в списках администратора, что просто не так визуально очевидно.
Так что я в буквальном смысле точно такое же поведение, как основные "страницы", но с моим пользовательским типом поста. Я зарегистрировал тип поста так, как ожидалось, и в админке он работает отлично - я могу назначить родителя и menu_order для каждого «поста» новостной рассылки, они правильно отображаются в списках редактирования:
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 - но мои, хотя и хорошо сформированные, не работают.
Что также сбивает с толку, так это когда я проверяю query_vars для этой страницы 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
)
источник
post_name
колонке./%postname%/
включение/%category%/
инспектора переписывания, похоже, только сбивает с толку. Я даже видел, как люди утверждают, что/%category%/
СРТ волшебным образом означает «родитель», хотя я не считаю, что это правда./blog/%postname%/
.Постоянная
parent/Child
ссылка работает из коробки, пока вы установитеОбновить:
Я только что проверил это снова, и он работает, как ожидалось, с этим тестовым примером:
и постоянная ссылка установлена, чтобы
/%postname%/
я получил информационный бюллетень / родитель / ребенок, работающий просто отлично.источник
page-attributes
поддержка (которая на самом деле только показывает метабокс для назначения происхождения, не должен влиять на постоянные ссылки) - но получение 404. Какую структуру постоянных ссылок нужно установить? или это имеет значение?register_post_type
$ args: я использовал'rewrite' => array( 'slug' => 'newsletter', 'with_front' => false )
, где вы использовали толькоtrue
. Кроме того, просто прошелtrue
дляhas_archive
, где я прошел слизняк. Однако, когда я совпал с твоими аргументами, у меня все равно было 404 ... Все еще пытаюсь отследить, где я иду не так.Помимо вопроса: « Вы пытались выключить и снова включить его?» , Я также должен спросить: «Есть ли у вас какие-либо плагины, и ваша тема что-то делает с постоянными ссылками (например, для регистрации таксономии, типов записей, добавления правил перезаписи)? , и т.д.)?
Если так: происходит ли это после того, как вы отключили все плагины и переключились на TwentyEleven?
Для дальнейшей отладки перейдите на GitHub и возьмите плагин Toschos "Rewrite" . Затем переключитесь на официальный репозиторий плагинов на wp.org и установите плагин MonkeyManRewriteAnalyzer . Я даже написал небольшое расширение, чтобы склеить немного вместе. Это даст вам много деталей о вашей настройке.
источник
Поэтому после подтверждения того, что я могу получить ожидаемое иерархическое поведение страницы с полностью чистой установкой и всего лишь одним объявлением 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()
делает, не загрязняя эти фильтры ...Вы используете самую последнюю версию WP? Я думаю, что это первый вопрос (например, когда вы звоните в службу технической поддержки, и они спрашивают вас, подключен ли ваш компьютер!), Так как я прочитал, что эта проблема была решена в самой последней версии обновления.
На digwp.com есть сообщение, посвященное этой проблеме (http://digwp.com/2011/06/dont-use-postname/). Очевидно, что WP не может легко определить разницу между сообщениями и страницами, и если вы начинаете свои URL-адреса с текстовой опцией, WP запускает флаг, который создает правило для каждой вашей страницы / публикации. Если у вас много контента на вашем сайте, это может привести к огромному количеству запросов, и ваш сервер, вероятно, истечет время ожидания, что приведет к куче 404, даже если страницы там есть.
Так. Если вы сначала используете числовую структуру, а затем текстовую структуру, я бы поспорил, что ваша проблема 404 будет решена. Теперь, учитывая проблемы SEO, я бы не стал использовать структуру дат, но принятие этого решения будет достаточно логичным для вас.
источник