Вопрос или проблема
Каждый раз, когда вы вводите URL с двумя сегментами пути, который не существует, WordPress автоматически интерпретирует запрос как вложение.
Как воспроизвести
- Измените структуру постоянных ссылок на
/%postname%/
. - Введите следующий путь после корневого URL вашего WordPress:
/foo/bar
, убедитесь, что “foo” не является существующей таксономией или типом записи. - Подключитесь к
pre_get_posts
и выведитеglobal $wp_query
. - Как видно из отладочной информации, система пытается интерпретировать URL как вложение, так как добавляет
post_type="attachment"
к запросу и некоторую другую информацию, связанную с вложениями. - Если не существует записи или страницы с именем из первого сегмента и вложения с именем из второго сегмента, то WordPress вернет 404.
ПРИМЕЧАНИЕ: Я не уверен в утверждениях, которые я сделал в шаге 2 и 5.
Почему это важно?
Мне очень не нравится иметь дело с этим поведением по умолчанию, и я действительно хотел бы как-то отключить это, если вы знаете как, пожалуйста, дайте мне знать. Это делает невозможным достижение некоторых структур постоянных ссылок. Вероятно, вы тоже хотите об этом знать. Я пытаюсь достичь такой структуры постоянных ссылок, где текущий слаг записи является префиксом ее слага термина. Например, тип записи ‘example’ имеет запись ‘bar’, которая имеет связь с термином со слагом ‘foo’. Вместо определения постоянной ссылки ‘example/bar’ она должна быть определена как ‘foo/bar’.
После того как я узнал немного больше о структуре постоянных ссылок по умолчанию и о том, как ее изменить, я наткнулся на хук rewrite_rules_array
. Этот хук позволяет вам фильтровать массив правил перезаписи, массив правил перезаписи URL в WordPress, что поможет определить, какой тип контента загружать.
Это отличное место, чтобы отключить поведение по умолчанию для распознавания пути как вложения. Так вы сможете избавиться от всех правил перезаписи для вложений, а значит, и от всего поведения, связанного с распознаванием пути как вложения.
add_filter('rewrite_rules_array', function($rules) {
foreach ($rules as $rule => $url) {
if (strpos($url, 'attachment') !== false) {
unset($rules[$rule]);
}
}
return $rules;
});
Я не уверен в остальных правилах и определенно хочу их все проверить. Например, эти:
"(.?.+?)(?:/([0-9]+))?/?$" => "index.php?pagename=$matches[1]&page=$matches[2]"
"([^/]+)(?:/([0-9]+))?/?$" => "index.php?name=$matches[1]&page=$matches[2]"
Помогут вам распознавать страницы, очень полезно знать, если вы хотите использовать только страницы. Но помните, если вы перезаписываете массив только с этими ключами/значениями, то новые правила, например, правила для вашего пользовательского типа записи также будут переписаны (удалены).
ПРИМЕЧАНИЕ: Отладка этого фильтра возможна только на странице Настройки > Постоянные ссылки в административной панели WordPress.
Ответ или решение
Чтобы отключить поведение WordPress, связанное с распознаванием пути как вложения, вам необходимо внести изменения в механизм перенаправления URL в вашей установке WordPress. Рассмотрим подробнее, как это можно сделать.
Проблема: Распознавание пути как вложения
Проблема заключается в том, что при использовании структуры постоянных ссылок /%postname%/
, WordPress пытается интерпретировать URL с двумя сегментами, которые не существуют, как вложение. Это может привести к тому, что система добавляет в запрос параметры, связанные с вложениями, и возвращает ошибку 404, если соответствующих записей не найдено. Например, если вы введете путь /foo/bar
, где foo
не является существующим таксономией или типом записи, WordPress попытается найти вложение с именем bar
, что приведет к нежелательному поведению.
Обоснование: Почему это важно
Это поведение может мешать созданию определенных структур постоянных ссылок, что может быть особенно проблематично при работе с пользовательскими типами записей и терминами. Например, если вы хотите, чтобы структура URL выглядела следующим образом: foo/bar
, где foo
— это слуг термина, а bar
— слуг записи, нужно отключить автоматическую интерпретацию пути как вложения.
Решение: Использование хука rewrite_rules_array
Для устранения этой проблемы вы можете использовать хук rewrite_rules_array
, который позволяет фильтровать массив правил перенаправления в WordPress. Основная идея заключается в том, чтобы удалить все правила, связанные с вложениями. Это можно сделать следующим образом:
add_filter('rewrite_rules_array', function($rules) {
foreach ($rules as $rule => $url) {
if (strpos($url, 'attachment') !== false) {
unset($rules[$rule]);
}
}
return $rules;
});
Этот код проходится по всем правилам и удаляет те, которые содержат ‘attachment’. Это позволит избежать попыток распознавания пути как вложения.
Учет других правил
Хотя удаление правил для вложений решает вашу проблему, важно отметить, что при внесении таких изменений необходимо внимательно изучить другие правила. Например, два правила:
"(.?.+?)(?:/([0-9]+))?/?$" => "index.php?pagename=$matches[1]&page=$matches[2]"
"([^/]+)(?:/([0-9]+))?/?$" => "index.php?name=$matches[1]&page=$matches[2]"
Эти правила используются для определения страниц и могут оказаться полезными, если вы хотите обрабатывать только страницы. Тем не менее, если вы перепишите массив правил, удалив все ключи и значения, это повлияет и на правила для ваших пользовательских типов записей.
Заключение
Проблема распознавания URL с несуществующими сегментами как вложений в WordPress может стать препятствием для реализации требуемых переменных структур постоянных ссылок. Использование фильтра rewrite_rules_array
позволяет удалить правила, которые связаны с вложениями, и тем самым избежать нежелательных ошибок. Будьте внимательны при работе с правилами перенаправления, чтобы не потерять функциональность других элементов вашего сайта.
Для отладки изменений не забудьте проверить настройки постоянных ссылок в панели управления WordPress. Это поможет удостовериться, что ваши изменения применяются корректно.