Пользовательская структура постоянных ссылок приводит к 404 ошибке при пагинации
У меня проблема с постоянными ссылками. Для информации: на сайте есть несколько разных категорий, и в каждой категории много записей.
Мои настройки постоянных ссылок:
Пользовательская структура: /%category%/%postname%/
Префикс категорий: . (точка)
После сохранения этих настроек мои URL выглядят так:
www.mydomain.com/category-slug-name/
вместо
www.mydomain.com/category/category-slug-name/
Я установил значение "На страницах блога отображать не более: 8 записей" в разделе "Настройки > Чтение". Пагинация появляется, когда в категории больше 8 записей.
Когда я нажимаю на "страница 2", замечаю, что www.mydomain.com/category-slug-name/page/2/
приводит к 404 ошибке.
Изначально URL второй страницы категории был www.mydomain.com/category/category-slug-name/page/2/
, и он работал нормально, когда в URL присутствовало "category". Без этого - 404 ошибка.
Моя основная проблема: я не хочу, чтобы "category" появлялось в URL. Но я хочу, чтобы slug категории отображался в URL при просмотре выбранной записи. И чтобы "/page/2/" и последующие страницы работали нормально.
Надеюсь, эту проблему можно решить без использования рекомендуемых плагинов, так как я не хочу перегружать сайт.
Есть предложения?

Это абсолютно нормальное поведение. Если вы хотите убрать базовый префикс категорий, вам нужно будет написать некоторые пользовательские правила перезаписи URL, и они не такие уж простые. С моей точки зрения, удаление базового префикса категорий требует дополнительной работы при каждом запросе, что не стоит усилий, так как не дает никаких преимуществ для SEO или улучшения навигации по сайту. Некоторые популярные плагины, такие как WordPress SEO от Yoast, имели эту опцию в прошлом, но убрали ее некоторое время назад. Но это всего лишь мнение.
Настройте базовый префикс категорий на .
(точку), поместите этот код в functions.php вашей темы, или лучше в плагин, и сбросьте правила перезаписи (код взят из этой статьи в Daily Web Kit):
add_filter( 'category_rewrite_rules', 'vipx_filter_category_rewrite_rules' );
function vipx_filter_category_rewrite_rules( $rules ) {
$categories = get_categories( array( 'hide_empty' => false ) );
if ( is_array( $categories ) && ! empty( $categories ) ) {
$slugs = array();
foreach ( $categories as $category ) {
if ( is_object( $category ) && ! is_wp_error( $category ) ) {
if ( 0 == $category->category_parent ) {
$slugs[] = $category->slug;
} else {
$slugs[] = trim( get_category_parents( $category->term_id, false, '/', true ), '/' );
}
}
}
if ( ! empty( $slugs ) ) {
$rules = array();
foreach ( $slugs as $slug ) {
$rules[ '(' . $slug . ')/feed/(feed|rdf|rss|rss2|atom)?/?$' ] = 'index.php?category_name=$matches[1]&feed=$matches[2]';
$rules[ '(' . $slug . ')/(feed|rdf|rss|rss2|atom)/?$' ] = 'index.php?category_name=$matches[1]&feed=$matches[2]';
$rules[ '(' . $slug . ')(/page/(\d)+/?)?$' ] = 'index.php?category_name=$matches[1]&paged=$matches[3]';
}
}
}
return $rules;
}

Я выполнил все согласно вашим инструкциям. Однако "/page/2" все еще не работает. Есть ли другие решения, чтобы это исправить? Спасибо!

Я проверил код перед публикацией, и он работает. Пожалуйста, как указано в ответе, не забудьте сбросить правила перезаписи (после копирования и сохранения кода перейдите в настройки->постоянные ссылки и нажмите "сохранить". Это заставит WordPress перестроить правила перезаписи с учетом новых).

Привет! Я попробовал. Ваш код для функции работает. Но я не могу добавить "точку" в базу категорий, и мне приходится использовать "301 Redirect" для перенаправления всех "domain.com/category/category-slug-name/" на "domain.com/category/category-slug-name/". Только "/page/2/" в таком случае работает.

Я проверил добавление точки в базу категории, как вы видите в ответе, и фактически эта точка необходима. Вы не упоминали о каких-либо редиректах, и способ, которым вы реализовали редирект, мне неизвестен — это отдельная проблема, которую нужно обсуждать в другом топике.

Привет, Cybmeta, у меня точка действительно не работает. Ничего страшного! В любом случае, спасибо за вашу помощь. Я всё равно проголосую за ваш ответ, так как вы мне помогли. :)

Лучше, если мы найдём решение ;). Вы сказали в вопросе, что точка работает, и я не понимаю, почему теперь она не работает; код из ответа обрабатывает пагинацию и фиды, но он никак не связан с точкой. Когда вы говорите, что это не работает, вы имеете в виду, что не работает с кодом из ответа или не работает даже без этого кода?

Страницы "/page/2/ и далее" не работают (перенаправляют на 404), если я ввожу "точку" в поле "Category Base" после применения вашего кода к моему файлу functions.php. Страницы "/page/2/ и далее" работают нормально только после того, как я удаляю "точку" из поля "Category Base". Но условие для их работы заключается в том, что мне нужно использовать перезапись правил в моем файле htaccess для перенаправления "/category/category-slug-name" на "/slug-name/".

Вы сбросили правила перезаписи после применения кода? Как я уже говорил, опубликованный код работает нормально. Возможно, у вас есть другой код, влияющий на правила перезаписи категорий. Попробуйте отключить все плагины и использовать стандартную тему. Кстати, перенаправление в файле htaccess следует делать только если у вас уже работающий сайт, который ранее использовал старую структуру URL, чтобы не потерять SEO-рейтинг и пользователей, переходящих по старым ссылкам; делать такое перенаправление на новом сайте бессмысленно.

Работает так, как заявлено. Также спасибо за то, что разместили код прямо в ответе, так как ссылка на блог больше не действительна.

Это сработало для меня. Добавьте эту функцию в файл functions.php вашего WordPress, и она изменит ваши ссылки:
Было: http://www.example.com/advice/category/category_name/page/3/
Стало: http://www.example.com/advice/category_name/page/3/
function remove_category_slug_url($query_string){
if ($query_string['name'] == 'page' && isset($query_string['page'])) {
unset($query_string['name']);
list($delim, $page_index) = explode('/', $query_string['page']);
$query_string['paged'] = $page_index;
}
return $query_string;
}
add_filter('request', 'remove_category_slug_url');

function
remove_category_slug_url($query_string){
if ($query_string['name'] == 'page' && isset($query_string['page'])) {
unset($query_string['name']);
list($delim, $page_index) = split('/', $query_string['page']);
$query_string['paged'] = $page_index;
}
return $query_string;
}
add_filter('request', 'remove_category_slug_url');
Этот код сработал для меня. Добавьте эту функцию в ваш файл functions.php в WordPress
Примечание: перейдите в Настройки->Постоянные ссылки и нажмите "Сохранить". Это заставит WordPress перестроить правила перезаписи с учетом новых.

Это сработало у меня.
function remove_page_from_query_string($query_string){
if ($query_string['name'] == 'page' && isset($query_string['page'])) {
unset($query_string['name']);
// 'page' в query_string выглядит как '/2', поэтому разделяю его
list($delim, $page_index) = split('/', $query_string['page']);
$query_string['paged'] = $page_index;
}
return $query_string;
}
add_filter('request', 'remove_page_from_query_string');
