Как использовать параметр offset без нарушения пагинации

Как использовать параметр “offset” без нарушения пагинации

В этой статье мы расскажем, как правильно использовать параметр offset в запросах WordPress.

Предполагается, что вы уже знакомы с тем, как использовать фильтры WordPress, и имеете представление о работе с классом wpdb.

Суть проблемы

Параметр offset позволяет разработчикам пропустить указанное количество постов перед началом их отображения. Однако многие новички сталкиваются с проблемой, когда использование параметра offset нарушает пагинацию на сайте.

Это логичное поведение, если понимать, что происходит. Аргумент offset используется WordPress при построении пагинации. Когда разработчики задают его вручную, пагинация перестает работать, так как этот аргумент перекрывается, и WordPress динамически изменяет его на каждой странице пагинации.

Решение проблемы

Чтобы использовать параметр offset в запросах WordPress и обеспечить корректную работу пагинации, необходимо динамически задавать offset для каждой страницы, учитывая первоначальный "сдвиг" постов. Также нужно пересчитать количество страниц в пагинации. Это можно сделать с помощью двух хуков:

  1. pre_get_posts - позволяет вмешаться в запрос перед его выполнением.
  2. found_posts - позволяет скорректировать количество найденных постов в запросе.

Корректировка offset и пагинации

Первый шаг

Используем хук pre_get_posts. Поскольку это действие, а не фильтр, нам нужно передать объект $query в нашу пользовательскую функцию по ссылке, что позволит нам напрямую изменить объект внутри класса.

Для начала нам нужно проверить, что мы изменяем нужный запрос:

add_action('pre_get_posts', 'myprefix_query_offset', 1 );
function myprefix_query_offset(&$query) {
    // Проверяем, является ли это нужным запросом...
    if ( ! $query->is_posts_page ) {
        return;
    }

    // Определяем требуемый offset...
    $offset = 10;

    // Определяем, сколько постов на страницу будем отображать (получаем из настроек)
    $ppp = get_option('posts_per_page');

    // Если это страница пагинации...
    if ( $query->is_paged ) {
        // Вычисляем offset на странице пагинации
        $page_offset = $offset + ( ($query->query_vars['paged']-1) * $ppp );

        // Применяем рассчитанный offset
        $query->set('offset', $page_offset );
    } else { // Если это первая страница
        // Используем только offset...
        $query->set('offset', $offset);
    }
}

Второй шаг

Теперь WordPress не будет учитывать наш offset при подсчете количества постов в запросе. Посты будут отображаться правильно, но когда WordPress будет строить номера страниц пагинации, он будет считать, что имеется еще 10 постов. Это приведет к созданию лишней страницы пагинации, которая будет возвращать пустой результат при нажатии на ссылку.

Эту проблему с пагинацией можно решить с помощью фильтра found_posts:

add_filter('found_posts', 'myprefix_adjust_offset_pagination', 1, 2 );
function myprefix_adjust_offset_pagination($found_posts, $query) {
    // Определяем наш offset снова...
    $offset = 10;

    // Проверяем, редактируем ли нужный запрос (на главной странице)...
    if ( $query->is_posts_page ) {
        // Изменяем количество найденных постов, уменьшаем на наш offset (10)...
        return $found_posts - $offset;
    }
}

Теперь все готово! Пагинация и необходимый offset должны работать корректно.

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *