Как отобразить один пост на главной странице, но при нормальном пейджинге?

9

Я хотел бы иметь один пост на моей первой странице (всегда последний), но пусть нормальный пейджинг работает. Таким образом, на первой странице есть пост 1, на следующей странице должен быть пост 2-11 (1-10 тоже хорошо), затем 12-21 или 11-20 и так далее. Я знаю, что могу изменить количество постов в зависимости от контекста , но если установить значение «1» на главной странице, это означает, что на других страницах также будет отображаться только один пост.

Моя главная проблема в том, что /page/2/и так далее работает, но /page/1/всегда перенаправляет на настоящую домашнюю страницу /. Это означает, что сообщения 2-10 всегда пропускаются, поскольку на странице 2 показано 11-20. В настоящее время я решаю эту проблему, ссылаясь на свой архив, но это не идеально, когда вы приходите на первые посты года, и там меньше постов и нет очевидного способа продолжения.

Ян Фабри
источник

Ответы:

7

Я решил его , используя в offsetпараметр запроса . Это позволило мне отредактировать запрос в pre_get_postsхуке, и, похоже, это самый чистый способ сделать это без нового запроса. Теперь домашняя страница показывает только один пост и page/2/показывает посты 2-11. Все ссылки продолжают работать, никаких других изменений не требуется.

add_action('pre_get_posts', 'set_offset_on_front_page');
function _set_offset_on_front_page(&$query)
{
    if (is_front_page() && is_paged()) {
            $posts_per_page = isset($query->query_vars['posts_per_page']) ? $query->query_vars['posts_per_page'] : get_option('posts_per_page');
            // If you want to use 'offset', set it to something that passes empty()
            // 0 will not work, but adding 0.1 does (it gets normalized via absint())
            // I use + 1, so it ignores the first post that is already on the front page
            $query->query_vars['offset'] = (($query->query_vars['paged'] - 2) * $posts_per_page) + 1;
    }
}
Ян Фабри
источник
Если это работает, то OP должен использовать это.
john010117
Что я и делаю, потому что я написал вопрос и этот ответ. Но спасибо за ваши предложения, они привели меня на правильный путь.
Ян Фабри
Есть ли возможность заставить его работать с archive.php или category.php, показывая только последние 2 сообщения на странице 1, сохраняя правильную нумерацию страниц? Спасибо!
Амит
@Amit: если вы замените is_front_page()на is_archive()или is_category(), я думаю, вы можете получить, где вы должны быть.
Ян Фабри
3

Хорошо, возможно, это странный или сложный способ сделать это, но у меня была похожая проблема (я хотел отобразить текст приветствия и три новейших сообщения определенной категории на первой странице. Итак, я сделал:

  1. Создал новую страницу под названием home и разместил на ней мой приветственный текст.
  2. Деактивировал домашнюю страницу по умолчанию и установил мою домашнюю страницу в качестве стартовой
  3. Создан новый (скопирован и изменен существующий) шаблон страницы
    1. пусть отображает тело страницы
    2. загрузить три новейших сообщения категории X и отобразить их
    3. под ним есть ссылка "more", которая ссылается на / category / category-x /

выглядит так: http://hinek.de (страница на немецком языке, извините)

Если вам это подходит, и вам нужна дополнительная информация или пример кода для шаблона страницы, оставьте комментарий, и я отредактирую этот пост.

Hinek
источник
Это работает, потому что вы отображаете сообщения только в категории «Сообщение ... какого-либо», и, таким образом, можете перейти на страницу этой категории и использовать обычную подкачку. Я хочу показывать сообщения из всех категорий, поэтому этот подход не будет работать для меня. У вас нет места, где люди могут просматривать все сообщения из всех категорий?
Ян Фабри
1

Я предполагаю, что вы используете Wordpress 3.0.x?

Показать только один пост (в любой категории) на первой странице легко. Используйте query_posts('post_per_page=1')в своем home.phpфайле вместо вызова get_template_part('loop').

Следовать обычным методам пейджинга после этого немного сложно. В вашем loop.phpфайле я предлагаю поставить <?php global $paged; ?>перед <?php if (have_posts()) : ?>оператором и использовать $pagedпеременную и query_posts()функцию для изменения вашего запроса, чтобы он отображал правильные сообщения.

Ваш loop.phpфайл будет выглядеть примерно так (примечание: не проверено):

<?php
global $paged;

if (!is_front_page() && $paged && $post->post_type == 'post') :
    query_posts('posts_per_page=10&paged=' . ($paged - 1));
    if (have_posts()) :
        while (have_posts()) : the_post();
        // Rest of the loop
        endwhile;
    endif;
endif;
?>

Я использовал $paged - 1просто потому, что на странице 2 будут показаны сообщения 1–10, а на странице 3 - сообщения 11–20 и т. Д.

john010117
источник
Изменение pagedпараметра не нарушит ничего другого, например next_posts_link? Может быть, лучше изменить запрос в pre_get_postsхуке, чтобы я не создавал новый запрос? И да, это WP 3.
Ян Фабри
AFAIK, это не должно влиять next_posts_link. Единственный способ выяснить это, конечно, попробовать.
john010117
1
Ага, если я попытаюсь отредактировать pagedпараметр в pre_get_postsхуке, redirect_canonicalвключится и захочет заменить URL новым pagedпараметром. В этом случае я могу отключить перенаправления, но next_posts_linkиспользую глобальную $pagedпеременную, для которой устанавливается новое значение, но я не знаю, по какому коду, поэтому она неверна.
Ян Фабри
Вы действительно пытались использовать мой код и посмотреть, работает ли он? Я не слишком знаком с pre_get_postsкрючком, поэтому я не могу помочь. Кроме того, попробуйте изменить $pagedпеременную напрямую (например, $paged = $paged - 1)если вы беспокоитесь) next_posts_link().
john010117
0

Этот вопрос немного стар, но для тех, кто находит это в современную эпоху, вы никогда не должны вызывать query_posts . Из кодекса Wordpress:

query_posts () - это слишком упрощенный и проблемный способ изменить основной запрос страницы, заменив его новым экземпляром запроса. Он неэффективен (перезапускает SQL-запросы) и в некоторых обстоятельствах потерпит неудачу (особенно часто при разбивке на посты).

...

TL; DR никогда не использует query_posts ();

Вместо этого вы должны использовать pre_get_postsхук в functions.php следующим образом:

function hwl_home_pagesize( $query ) {
    // Behave normally for secondary queries
    if ( is_admin() || ! $query->is_main_query() )
        return;

    if ( is_home() ) {
        // Display only 1 post for the home page
        $query->set( 'posts_per_page', 1 );
        return;
    }

    // Otherwise, use whatever is set in the Wordpress Admin screen
    $query->set( 'posts_per_page', get_option('posts_per_page'); );
}
add_action( 'pre_get_posts', 'hwl_home_pagesize', 1 );

Тем не менее, имейте в виду, что в некоторых случаях (например, корректировка смещения постов) использование pre_get_postsхука может испортить вашу нумерацию страниц. Исправить это не очень сложно, но это то, что нужно знать. Вот пример того, как это исправить здесь .

lfalin
источник