Как включить category-base в постоянных ссылках записей без ошибки 404
У меня есть статическая главная страница и отдельная страница /news/
в качестве страницы записей. Я хочу, чтобы URL отдельных записей выглядели так:
www.example.com/news/categoryname/subcategory/postname/
А для архивов категорий:
www.example.com/news/categoryname/
Что я уже пробовал:
Если я добавляю
news
как базу категорий и/news/%category%/%postname%/
в качестве пользовательской структуры постоянных ссылок, я получаю желаемые URL, но также 404 ошибку для отдельных записей (как сnews/
в URL, так и без него). Все остальные страницы (например, архивы категорий, страницы и т.д.) доступны.Если я оставляю базу категорий пустой и устанавливаю постоянные ссылки как
/news/%category%/%postname%/
, нет 404 ошибок, но URL категорий дополнительно содержат стандартный слагcategory
, например:www.example.com/news/category/categoryname/
Если я использую плагины для удаления стандартной базы категорий или просто устанавливаю базу категорий как
.
, она удаляется вместе с частьюnews
Если я устанавливаю постоянные ссылки как
/%category%/%postname%/
и добавляю только базу категорийnews
, также нет 404 ошибок, но ссылки на записи не начинаются сnews
:www.example.com/categoryname/subcategory/postname/
Есть несколько похожих вопросов без ответов: Записи не отображаются с пользовательской базой категорий и подкатегориями и Настройки постоянных ссылок WordPress

Вам нужно просто добавить "/." после основы категории:
Основа категории: news/.
(/. обязательно, так как предотвращает 404 ошибки для записей).
У меня это сработало идеально :)
ПРИМЕЧАНИЕ: Это поле удаляет завершающие или начальные слеши, если вы не добавите "."

Я вернулся к этой проблеме недавно и наконец-то нашел решение! Оно может сработать или не сработать у вас — есть два возможных случая:
Если некоторые записи на вашем сайте находятся в родительских категориях, а некоторые — в подкатегориях (дочерних категориях), или категории имеют разный уровень вложенности (у некоторых родительских категорий есть только подкатегории, а у других — под-подкатегории), то решения нет. Невозможно отличить
news/category/post-name/
отnews/category/subcategory/
с помощью регулярных выражений в правилах перезаписи.Если у вас фиксированный уровень вложенности для всех категорий, и записи размещаются только в подкатегориях последнего уровня, то вам повезло! Решение довольно простое:
Причина появления 404 ошибок при использовании news
как в базе категорий, так и в структуре постоянных ссылок заключается в том, что внутреннее правило перезаписи базы категорий имеет приоритет над правилами структуры постоянных ссылок. Таким образом, news/category/subcategory/postname/
интерпретируется как index.php?category_name=category/subcategory/postname
, и, очевидно, WordPress не может найти такую категорию, возвращая страницу 404.
Что вам нужно сделать — добавить новое правило перезаписи в начало списка правил. Поместите этот код в ваш functions.php
или в любое другое подходящее место:
add_action( 'init', 'wpa58471_category_base' );
function wpa58471_category_base() {
// Не забудьте вручную сбросить правила перезаписи один раз после добавления этого кода!
add_rewrite_rule(
// Регулярное выражение для сопоставления входящего URL
'news/([^/]+)/([^/]+)/([^/]+)(/[0-9]+)?/?$',
// Результирующий внутренний URL
'index.php?category_name=$matches[1]/$matches[2]&name=$matches[3]&paged=$matches[4]',
// Добавляем правило в начало списка перезаписи
'top' );
}
а затем обновите структуру постоянных ссылок на странице общих настроек WordPress. Приведенный выше код предназначен для двухуровневой вложенности. Если у вас больше или меньше уровней вложенности категорий, отредактируйте регулярное выражение и итоговый URL соответствующим образом.
P.S. Спасибо участникам этих полезных обсуждений: помощь с add_rewrite_rule и инструмент для анализа правил перезаписи.

Хотя нет решения с использованием регулярных выражений в правилах перезаписи, все же есть способ реализовать эту функциональность: http://wordpress.stackexchange.com/questions/98083/how-can-you-load-the-categories-page-from-a-hook/98095#98095

Пользовательская структура постоянных ссылок: /media/%category%/%postname%/
База для рубрик: .
Сработало у меня на WordPress 3.4.1 без каких-либо дополнительных плагинов.
Обновление: Позже я заметил, что функция wp_list_categories
выводит ссылки без "media" в URL. Однако записи доступны по желаемой структуре URL, и архивы рубрик находятся в правильном месте.
Сейчас я изучаю возможность изменения поведения функции wp_list_categories.

Спасибо за ответ, но есть 2 проблемы: я не могу получить доступ к архивам категорий (как с media
, так и без него, используя ту же версию 3.4.1), и фактически сгенерированные ссылки содержат /./
в своих адресах.

Это странно. Полагаю, может быть 2 причины: 1. Некоторые из ваших плагинов дают побочные эффекты. 2. Моя начальная настройка WordPress как-то отличается. Я использую http://qwordpress.ru/ с немедленным обновлением до текущей версии WP. И в этом случае первое, над чем я работал - это структура категорий и URL, так что настройка была довольно чистой.

Лучше бы я оставил комментарий, но пока не могу. Ваш код работает отлично, но если вы не хотите нарушать RSS-ленты для категорий, он должен выглядеть так:
add_action( 'init', 'wpa58471_category_base' );
function wpa58471_category_base() {
// Не забудьте вручную сбросить правила перезаписи после добавления этого кода!
add_rewrite_rule(
// Регулярное выражение для сопоставления входящего URL
'news/([^/]+)/([^/]+)/([^/][^f][^e][^e][^d]+)(/[0-9]+)?/?$', //здесь мои изменения для исключения 'feed'
// Результирующий внутренний URL
'index.php?category_name=$matches[1]/$matches[2]&name=$matches[3]&paged=$matches[4]',
// Добавляем правило в начало списка перезаписи
'top' );
}
В любом случае, спасибо за отличный пример кода. :)
