Comment afficher un seul article sur la première page mais avoir une pagination normale?

9

Je voudrais avoir un seul article sur ma première page (toujours le dernier), mais laisser la pagination normale fonctionner. Donc, la première page a le post 1, la page suivante devrait avoir le post 2-11 (1-10 est très bien aussi), puis 12-21 ou 11-20, et ainsi de suite. Je sais que je peux changer le nombre de messages en fonction du contexte , mais le définir sur "1" sur la page d'accueil signifie que les pages suivantes ne montrent également qu'un seul message.

Mon principal problème est que /page/2/, etc. œuvres, mais /page/1/redirige toujours à la vraie page d'accueil, /. Cela signifie que les messages 2-10 sont toujours ignorés, car la page 2 affiche 11-20. Je résous actuellement ce problème en créant un lien vers mes archives, mais ce n'est pas idéal lorsque vous arrivez aux premiers messages de l'année et il y a moins de messages et aucun moyen évident de continuer.

Jan Fabry
la source

Réponses:

7

Je l'ai résolu en utilisant le offsetparamètre de requête . Cela m'a permis de modifier la requête dans le pre_get_postscrochet, et semble être le moyen le plus propre de le faire, sans nouvelle requête. Maintenant, la page d'accueil n'affiche qu'un seul message et page/2/affiche les messages 2-11. Tous les liens continuent de fonctionner, aucune autre modification n'est requise.

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;
    }
}
Jan Fabry
la source
Si cela fonctionne, l'OP devrait l'utiliser.
john010117
Ce que je fais, parce que j'ai écrit la question et cette réponse. Mais merci pour vos suggestions, elles m'ont amené sur la bonne voie.
Jan Fabry
Est-il possible de le faire fonctionner sur un fichier archive.php ou category.php, affichant uniquement les 2 derniers messages de la page 1 tout en conservant une pagination correcte? Merci!
Amit
@Amit: Si vous remplacez is_front_page()par is_archive()ou is_category(), je pense que vous pouvez arriver là où vous devez être.
Jan Fabry
3

Ok, c'est peut-être une façon étrange ou compliquée de le faire, mais j'ai eu un problème similaire (je voulais afficher un texte de bienvenue et les trois derniers messages d'une catégorie spécifique sur la première page. J'ai donc fait:

  1. J'ai créé une nouvelle page appelée home et y ai mis mon texte de bienvenue.
  2. Désactivé la page d'accueil par défaut et définir ma page d'accueil personnalisée comme page de démarrage
  3. Création d'un nouveau modèle de page (copié et modifié un modèle existant)
    1. laissez-le afficher le corps de la page
    2. charger trois nouveaux messages de la catégorie X et les afficher
    3. avoir un lien "plus" en dessous qui relie sur / catégorie / catégorie-x /

ressemble à ceci: http://hinek.de (la page est en allemand, désolé)

Si cela peut être le moyen pour vous et que vous avez besoin de plus d'informations ou d'un exemple de code pour le modèle de page, commentez et je modifierai ce message.

Hinek
la source
Cela fonctionne parce que vous affichez uniquement les messages dans la catégorie "Message de la ... quoi que ce soit", et pouvez donc accéder à cette page de catégorie et utiliser la pagination normale. Je souhaite afficher les messages de toutes les catégories, cette approche ne fonctionnera donc pas pour moi. Vous n'avez aucun endroit où les gens peuvent parcourir tous les messages de toutes les catégories?
Jan Fabry
1

Je suppose que vous utilisez Wordpress 3.0.x?

Pour afficher un seul article (dans n'importe quelle catégorie) sur la première page est facile. Utilisez query_posts('post_per_page=1')dans votre home.phpfichier au lieu d'invoquer get_template_part('loop').

Suivre les méthodes de pagination normales après cela est un peu délicat. Dans votre loop.phpfichier, je suggère de mettre <?php global $paged; ?>avant l' <?php if (have_posts()) : ?>instruction et d'utiliser la $pagedvariable et la query_posts()fonction pour modifier votre requête afin qu'elle affiche les bons messages.

Votre loop.phpfichier ressemblerait à ceci (remarque: non testé):

<?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;
?>

J'ai utilisé $paged - 1simplement parce que la page 2 affichera les messages 1 - 10, et la page 3 affichera les messages 11 - 20, et ainsi de suite.

john010117
la source
Changer le pagedparamètre ne cassera rien d'autre, comme le next_posts_link?. Il est peut-être préférable de modifier la requête dans le pre_get_postscrochet, donc je ne crée pas de nouvelle requête? Et oui, c'est WP 3.
Jan Fabry
AFAIK, cela ne devrait pas affecter next_posts_link. La seule façon de le savoir est bien sûr de l'essayer.
john010117
1
Argh, si j'essaye d'éditer le pagedparamètre dans le pre_get_postscrochet, entre redirect_canonicalen action et veut remplacer l'url par le nouveau pagedparamètre. Je peux désactiver les redirections dans ce cas, mais next_posts_linkutilise une $pagedvariable globale qui est définie sur la nouvelle valeur, mais je ne sais pas par quel code, donc c'est incorrect.
Jan Fabry
Avez-vous réellement essayé d'utiliser mon code et de voir s'il fonctionnait? Je ne connais pas trop le pre_get_postscrochet, donc je ne peux pas être très utile là-bas. Essayez également de modifier la $pagedvariable directement (ex:) $paged = $paged - 1)si cela vous inquiète next_posts_link().
john010117
0

Cette question est un peu ancienne, mais pour ceux qui trouvent cela à l'ère moderne, vous ne devriez jamais appeler query_posts . Du codex Wordpress:

query_posts () est un moyen trop simpliste et problématique de modifier la requête principale d'une page en la remplaçant par une nouvelle instance de la requête. Il est inefficace (réexécute les requêtes SQL) et échouera carrément dans certaines circonstances (en particulier souvent lors de la pagination des publications).

...

TL; DR n'utilise jamais query_posts ();

Au lieu de cela, vous devez utiliser le pre_get_postshook dans functions.php comme suit:

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 );

Cependant, sachez que dans certains cas (comme l'ajustement des décalages de poteau), l'utilisation d'un pre_get_postscrochet peut altérer votre pagination. Corriger cela n'est pas super difficile, mais c'est quelque chose dont il faut être conscient. Il y a un exemple de comment résoudre ce problème ici .

lfaline
la source