Lorsqu'on travaille sur des thèmes assez complexes, disons orienté magazine, on a généralement besoin d'afficher un nombre d'articles différents selon la ou on se situe... 5 pour la recherche, 8 pour les archives, etc.
Pour y parvenir, il y a 2 possibilités, installer une extension ou créer une fonction dans le thème.
- L'extension a l'avantage d'être configurable depuis la console d'administration, le défaut c'est qu'on charge un peu plus de choses dans WordPress... Et puis pourquoi mettre personnalisable quelque chose de statique dans la vie de tous les jours...
- La deuxième méthode consiste à placer une fonction directement dans le fichier functions.php de votre thème. Cette fonction sera associée au filtre "pre_get_posts" de WordPress.
Fonction d'exemple:
add_filter( 'pre_get_posts', 'quantity_per_view' );
function quantity_per_view( $wp_query = '' ) {
if ( is_search() ) { // recherche
$wp_query->query_vars['posts_per_page'] = 9;
} elseif ( is_category() ) { // Category
$wp_query->query_vars['posts_per_page'] = 8;
} elseif ( is_tag() ) { // Tag
$wp_query->query_vars['posts_per_page'] = 8;
} elseif ( is_author() ) { // Auteur
$wp_query->query_vars['posts_per_page'] = 8;
} elseif ( is_date() ) { // Archive
$wp_query->query_vars['posts_per_page'] = 8;
}
return $wp_query;
}
Ici, on permet de spécifier une quantité différente pour la vue, les catégories, les tags, les auteurs et les archives... La valeur que vous fixerez écrasera l'option présente dans la page de réglages "Lecture" de WordPress.
Je conclurai en disant que cette méthodologie est l'unique bonne méthode pour spécifier le nombre d'articles par page. Utilise la fonction query_posts() est une aberration digne de tout bon webdesigner en herbe pour la simple et bonne raison que vous effectuerez le double de requête SQL...
Cela aura comme conséquence d'augmenter la charge serveur et le temps de génération des pages ;) Si les créateurs de thèmes magazine US (Mimbo et ses petits cousins) me lisent (ce qui est compliqué), prenez de la graine !
2 mars 2009 à 17:16
Merci pour la fonction, ça va pouvoir me servir :-)
2 mars 2009 à 21:21
« Utilise la fonction query_posts() est une aberration digne de tout bon webdesigner en herbe »
Je sais pas pourquoi mais je me sens visé par cette remarque !! :D
Mais cela dit, je suis d’accord, utiliser les queries uniquement pour changer le nombre d’articles à afficher est idiot !! On ne m’y reprendra plus…….. jusqu’à la prochaine fois !! :P
2 mars 2009 à 21:58
@ Francis » Pas de raison de te sentir visé, je pense que pratiquement tout le monde balance du query_post() dans ses thèmes et Amo souligne à juste titre pourquoi c’est une mauvaise pratique.
@ Amo » Un excellent post ici qui mérite de devenir une référence ! Peux-tu nous préciser le pourquoi du
!is_category(1)de ton exemple ? La catégorie d’id 1 a-t-elle quelque chose de spécial ?
(Autre chose qui n’a rien à voir, mais le système de création automatique de lien sur chaque mot correspondant à un tag me semble plus générateur de bruit que porteur d’une vraie valeur ajoutée pour tes lecteurs – mon avis personnel, bien sûr !)
2 mars 2009 à 22:00
C’est bien la peine que je mette des balises >strong< dans mon commentaire !
3 mars 2009 à 0:19
Francis > Ca n’est pas pour toi. Tu n’a pas créer Mimbo ;)
CuI > Euh, en fait cette condition n’a rien à foutre dans cet exemple, c’est pour les besoin de WP-FR ;) (code updated)
Pour les tags, je suis d’accord avec toi, ca ne sert pas à grand chose, mais honnêtement HWM est mon labo, je dev sur Simple Tags direct sur mon blog, d’ou la raison pourquoi ils sont activés ;)
7 mars 2009 à 1:00
Voilà le genre d’article que l’on aimerait lire plus souvent. Quelques lignes simples et propres pour régler un vrai problème. Et un rappel sur le fait qu’un thème mal codé peut dégrader terriblement les performances de WordPress. Attention donc avant de se précipiter sur un thème « super bôooo », d’autant qu’on va rarement regarder comment il est « fabriqué »…
9 mars 2009 à 20:19
Bizarre, je ne reçois pas les updates par email alors que j’y suis abonné… Enfin bon, tout ça pour dire qu’il est grand temps que je me mette au php, ras le bol d’être limité à ce niveau-là !! :D … maintenant, va falloir trouver le temps…
Pingback : LbSquat » Blog Archive » LbSquat is back!!
10 mars 2009 à 7:51
Merci beaucoup pour cette petite fonction vraiment très pratique.
12 mars 2009 à 22:31
Francis > Pour les notifications mail, c’est corrigé ;)
20 mars 2009 à 5:45
S@lut Am
20 mars 2009 à 5:49
S@lut Amaury (et salut aux autres aussi bien sur),
Merci pour cette fonction très pratique,je cherche à faire quelque chose de similaire à cause du sticky. C’est à dire que j’aimerais sur l’accueil qu’il y ait 4 posts qui s’affichent et 6 sur les pages suivantes. J’imagine qu’avec ta fonction c’est possible, non?
P.S : Désolé pour le commentaire précédent foiré (il est tôt), tu peux le supprimer sans souci :D
Didier.
4 avril 2009 à 18:02
Bonjour ! Et merci pour cette solution qui semble fonctionner à merveille. Une petite question : comment fait-on pour régler l’affichage sur une page en particulier avec cette fonction ? Je veux par exemple avoir un nb de billets, et ceux de quelques catégories seulement.
A partir du code ci-dessus, j’ai tenté :
} elseif ( is_page('annonces') ) { // Annonces$wp_query->query_vars['posts_per_page'] = 3;
$wp_query->query_vars['cat'] = 52,54,55;
Apparemment, ça ne fonctionne pas. J’ai été alors obligé d’utiliser le query_posts dans cette page annonces pour avoir ce que je voulais, mais voilà, la pagination page 1, page 2, etc, ne fonctionne pas. Bref, je tourne en rond ! Si quelqu’un a une lumière. Même dans le livre WordPress du trio Francis-Xavier-Amaury, je n’ai pas trouvé. Il faut dire que je suis encore débutant en WP ;-)
Mais là, je sèche, même avec l’excellent livre WordPress écrit par le trio Francis-Xavier-Amaury.
4 avril 2009 à 18:04
Euh, là, j’en ai fait un peu trop sur le livre. Un copier coller trop rapide. Ca fait de la pub à bon compte… ;-)
6 avril 2009 à 15:14
Wolforg > Tu as essayé ca :
add_filter( ‘pre_get_posts’, ‘quantity_per_view’ );
function quantity_per_view( $wp_query = » ) {
global $paged;
if ( is_home() || $paged < = 1 ) { // home, page 1
$wp_query->query_vars['posts_per_page'] = 4;
} elseif( is_home() ) { // Home page ++
$wp_query->query_vars['posts_per_page'] = 6;
}
}
6 avril 2009 à 15:15
Stéphan > Pourquoi ne pas avoir simplement fait une catégorie à la place d’une page ? (et éventuellement avec un query_posts(), appeler le contenu de la page Annonces ?
6 avril 2009 à 15:35
S@lut Amaury et merci de ta réponse :)
Je viens d’essayer ta modif’, mais cela me fournit un superbe « Parse error: syntax error, unexpected ‘=’ in /homepages/34/d140709433/htdocs/ail/wp-content/themes/chameleon_1-1/functions.php on line 193″. La ligne 193 correspondant à :
if ( is_home() || $paged < = 1 ) { // home, page 1Ettonant, non? ;-)
6 avril 2009 à 15:49
Il ne faut pas faire de copier/coller depuis les commentaires ;)
6 avril 2009 à 16:34
Salut Amaury !
J’ai opté pour la page plus que pour la catégorie parce que je souhaite intégrer en bout de liste un formulaire pour passer une annonce. Il ne me semblait pas possible de le faire sur une page Catégorie. J’utilise Contact Form 7. Et puis, si je ne me trompe pas, l’usage du query_posts posera quand même problème pour la nav sur la page de la catégorie concernée, non ?
10 avril 2009 à 14:44
Salut,
Pour moi c’est pas jojo, effectivement ça fait ce que je demande, mais ça me crée 2 erreurs java sous IE, et ça me bloque carrément le site sous firefox!
Piti problème! Dommage :(
10 avril 2009 à 17:21
Ne pas faire de copier coller bête depuis ici, en général les quotes sont déformés…
14 mai 2009 à 8:57
Tiens j’ai retenté, ça marche :)
Merci beaucoup!
2 juin 2009 à 21:22
Bonjour Amaury,
J’ai utilisé cette fonction qui et vraiment géniale mais je m’aperçois qu’elle n’est pas prise en compte dès lors que j’utilise la réécriture des permaliens sous forme de /%category%/%postname%
Est-ce qu’il existe une solution ou suis-je obligé d’utiliser la forme d’url par défaut ?
Merci.
3 juin 2009 à 9:33
J’utilise ce format de réécriture sur les sites ou je travaille et je n’ai aucun problème avec la limite du nombre d’articles…
Toi ca buggue dès que tu actives les permaliens ? (tout format ?)
3 juin 2009 à 10:13
Bonjour Amaury,
tu as raison, ta fonction marche parfaitement bien avec tous les permaliens.
C’est en fait mon utilisation de ta fonction qui ne marche pas.
En fait je voudrais afficher un nombre d’articles différent selon les categories.
ce qui donne ça :
query_vars['posts_per_page'] = 4;
} elseif ( is_category(‘journal’) ) { // catégorie nommée ‘journal’
$wp_query->query_vars['posts_per_page'] = 6;
} elseif ( is_category() ) { // Les autres catégories
$wp_query->query_vars['posts_per_page'] = 8;
}
return $wp_query;
}
?>
Cette fonction marche très bien si les permaliens ont la forme par défaut, en revanche ça ne fonctionne plus si on passe à une autre forme de permaliens.
Il y a surement une erreur dans ma manière de coder.
Je te remercie pour ta réponse et pour ton blog en général :-)
3 juin 2009 à 10:14
Je te remets la fonction telle que je l’utilise, elle n’est pas bien passée dans le 1er message
add_filter( ‘pre_get_posts’, ‘quantity_per_view’ );
function quantity_per_view( $wp_query = » ) {
if ( is_category(‘news’) ) { // catégorie nommée ‘news’
$wp_query->query_vars['posts_per_page'] = 4;
} elseif ( is_category(‘journal’) ) { // catégorie nommée ‘journal’
$wp_query->query_vars['posts_per_page'] = 6;
} elseif ( is_category() ) { // Les autres catégories
$wp_query->query_vars['posts_per_page'] = 8;
}
return $wp_query;
}
3 juin 2009 à 17:45
Amaury, je reviens voir par ici car je ne sais pas comment pointer une catégorie pour lui attribuer un nombre particulier d’articles à afficher.
if ( is_category(’news’) ) ne semble pas fonctionner autrement qu’avec le permalien par défaut.
Comment puis-je contourner le problème ?
merci
13 juin 2009 à 14:21
10 jours plus tard j’ai toujours mon problème. Je désespère. je ne sais pas pointer une catégorie particulière pour qu’elle n’affiche qu’un certain nombre d’articles :-/
13 juin 2009 à 14:51
Seb > Il faut travailler avec les ID et non les slugs sur ce hook.
13 juin 2009 à 16:01
Merci amo pour la réponse mais malheureusement j’ai déjà essayé ça et même avec les id ça ne fonctionne pas à partir du moment où j’utilise une autre forme de permalien que la forme par défaut.
Avec la forme par défaut, aucun problème, même en utilisant les slug, mais sinon, ça ne marche pas.
es-tu certain que tu as réussi sur tes sites à déclarer 2 nombres d’articles différents à afficher dans deux catégories différentes avec une forme autre que celle par défaut ?
Si c’est le cas et sans vouloir abuser j’aimerais bien voir comment tu as codé ça.
encore merci.
14 juin 2009 à 21:18
Amaury,
tout d’abord merci pour tout. Je suis un peu dégouté car j’aimais beaucoup ta fonction mais il semble que je sois un bien piètre développeur car je ne suis pas parvenu à cibler des catégories ni avec les id ni avec les slugs (en tout cas pas en utilisant une autre forme de permalien que celle par défaut). En désespoir de cause, je me suis rabattu sur ce plugin http://www.maxblogpress.com/plugins/dppp/ qui semble fonctionner très bien.
Si d’aventure tu pouvais vérifier que tu arrives bel et bien à cibler une catégorie, à lui attribuer un nombre d’articles particulier, et tout ça avec une forme de permalien autre que la forme par défaut, je serai heureux de le savoir (ça me confirmerait qu’il faut décidément que j’arrête définitivement toute tentative dans le domaine du php). Si en revanche tu me confirmais le contraire, j’aurais au moins le plaisir de penser que je n’ai pas perdu ces heures en vain :-)
et si tu allais jusqu’à me dire où se situait l’erreur je crois que je te baiserais les pieds et dresserais illico une statue à ton effigie :-)
14 juin 2009 à 22:16
Tu as essayé sur le modèle suivant :
< ?php $cat_id = (int) get_query_var('cat'); $category_name = trim(get_query_var('category_name')); if ( $cat_id != 0 ) { // If there's a category ID without Permalink // Use method with ID } elseif ( !empty($category_name) ) { // Use permalink if ( stristr($category_name,'/') ) { $category_name = explode('/',$category_name); if ( $category_name[count($category_name)-1] ) $category_name = $category_name[count($category_name)-1]; // no trailing slash else $category_name = $category_name[count($category_name)-2]; // there was a trailling slash } // Soit tu testes le slug, soit tu récupères l'ID depuis le slug... $cat = get_term_by('slug', $category_name, 'category', OBJECT, 'display'); if ( $cat ) { $cat_id = $cat->term_id; } } if ( $cat_id == 3 ) { global $wp_query; // Blabla ;) } ?>20 juin 2009 à 10:17
我笑笑!
20 juin 2009 à 12:26
我也准备换成你这样的了!
5 juillet 2009 à 9:16
貌似有点道理
5 juillet 2009 à 9:41
很舒服的模板
12 septembre 2009 à 0:17
Après avoir un peu creusé pour comprendre pourquoi le truc donné à Wolforg ne marchait pas, j’ai le plaisir de vous indiquer la soluce !
Il ne faut pas utiliser global $paged mais $wp_query->query_vars['paged']
Ça donne ça :
if ( is_home()) { // home, page 1
$wp_query->query_vars['posts_per_page'] = ($wp_query->query_vars['paged'] <= 1) ? 7 : 12 ;
} elseif ( is_search() ) { // recherche
12 septembre 2009 à 9:45
Comme une image > dans ton code, j’imagine que 12 est le nombre d’articles sur la home, mais que représente le 7 s’il te plait ?
12 septembre 2009 à 9:53
@ Sébastien »
La notation
(condition) ? valeur1 : valeur2se comprend ainsi :Si la condition est vraie, retourner valeur1 sinon retourner valeur2.
Donc, dans mon code, si je suis sur la home, de deux choses l’une : soit je suis sur la 1ère page, dans ce cas j’affiche 7 articles, soit non, et j’en affiche 12.
12 septembre 2009 à 9:58
Comme une image > Ah Ok, oui, excuse-moi, je ne suis pas familier de cette forme de notation.
Comme tu peux le voir dans les précédents commentaires, j’avais pour ma part essayer à une époque de cibler les catégories pour leur affecter des nombres d’articles différents mais ça ne marchait pas dès lors que mes permaliens étaient personnalisés /%category%/%postname%
Est-ce que tu as une idée pour résoudre ce problème ?
12 septembre 2009 à 11:11
@cui :
Ce que je préfère dans la mentalité « Open Source » c’est qu’une question ne reste que très rarement sans réponse ;-)
C’est plus ou moins rapide selon la question mais comme dirait l’autre « Vieux motard que jamais » :-D
Merci à toi Jérome donc, et au plaisir de te recroiser (ainsi qu’Amaury) à un prochain Wordcamp :-)
Ré@gissons, p@rticipons…
12 septembre 2009 à 13:23
J’avoue, Wolforg, que je me suis mis vraiment à chercher que lorsque j’en ai eu besoin ;-) Mais bon, c’est le résultat qui importe.
Sébastien, j’ai regardé un peu le source de wp-include/query.php, j’ai fait des tests et j’ai réussi, je crois, à trouver un truc qui fonctionne (chez moi, en tout cas) :
Remplace
if (is_category('slug'))parif ($wp_query->query_vars['category_name'] == 'slug')12 septembre 2009 à 13:36
@ cui : C’est là que réside la grande force du libre, on s’entraide non pas parce que l’on éprouve le besoin d’aider mais plutôt car nos besoins convergent à un moment donné sur un sujet précis, cela s’appelle les réseaux de coopération faibles je crois. Linux s’est monté comme cela et nos politiques seraient bien inspirés de s’en …inspirer justement :-p
17 septembre 2009 à 11:08
@ tous » Je me suis aperçu d’un petit problème quand on utilise un nombre d’articles différents sur la home (mettons qu’on en ait 6 sur la home et 10 sur les autres pages, la page 1 va afficher les articles 1 à 6 et la page 2 les articles 10 à 20, exit donc les article 7 à 9 !
Il faut donc positionner l’offset.
Voici donc ce que donne ma fonction après mise au point :
function cui_quantity_per_view( $wp_query = '' ) {//global $paged;
$nb_home = 7; // Home page
$nb_def = $wp_query->query_vars['posts_per_page']; // Valeur par défaut, définie dans l'interface (Réglages/Lecture)
$nb_search = 20; // Search pages
// Optimiser en regroupant par valeurs identiques une fois les valeurs fixées
if ( is_home()) { // home, page 1
$page = absint($wp_query->query_vars['paged']);
if ($page query_vars['posts_per_page'] = $nb_home ;
} else {
$wp_query->query_vars['offset'] = ($page-2) * $nb_def + $nb_home ;
// $wp_query->query_vars['posts_per_page'] = $nb_def ;
}
} elseif ( is_search() ) { // recherche
$wp_query->query_vars['posts_per_page'] = $nb_search;
}
// else : on garde la valeur par défaut
return $wp_query;
}
Dans cet exemple, on utilise pour toutes les pages la valeur par défaut définie dans l’interface WordPress, sauf pour la Home et les résultats de recherche.
17 septembre 2009 à 11:11
Hum… ça s’affiche bizarre. Je reposte la fonction !
function cui_quantity_per_view( $wp_query = '' ) {//global $paged;
$nb_home = 7; // Home page
$nb_def = $wp_query->query_vars['posts_per_page']; // Valeur par défaut, définie dans l'interface (Réglages/Lecture)
$nb_search = 20; // Search pages
if ( is_home()) { // home, page 1
$page = absint($wp_query->query_vars['paged']);
if ($page query_vars['posts_per_page'] = $nb_home ;
} else {
$wp_query->query_vars['offset'] = ($page-2) * $nb_def + $nb_home ;
// $wp_query->query_vars['posts_per_page'] = $nb_def ;
}
} elseif ( is_search() ) { // recherche
$wp_query->query_vars['posts_per_page'] = $nb_search;
}
// else : on garde la valeur par défaut
return $wp_query;
}
17 septembre 2009 à 11:16
Hop une dernière précision à ce sujet.
Pour n’affecter qu’une seule fois le requête WP_Query.
Il suffit de placer la fonction
remove_filter( ‘pre_get_posts’, ‘quantity_per_view’ );
A l’intérieur de la fonction quantity_per_view.
Cela permet d’auto-désactiver la fonction et ainsi on peut utiliser plusieurs fois la méthode query_posts sans aucun problème !
17 septembre 2009 à 11:17
CUI > Si le code passe mal, passe via un service de partage de code ;)
Pingback : One Chapter a Day » Afficher un nombre d’articles différents par page
27 novembre 2010 à 11:18
Je suis d’accord avec Sebastien. il est impossible d’utiliser cette function avec le permaliens /%postname%/
Quelqu’un at-il une idée?
18 janvier 2012 à 15:40
Pas mal comme astuce ! Ca date un peu mais c’est exactement ce que je cherchais :) Merci beaucoup pour le partage !