J'ai une série de messages qui sont classés par valeur meta_key. Ils peuvent également être organisés par ordre de menu, si nécessaire.
Les liens de publication suivants / précédents (générés par next_post_link
, previous_post_link
ou posts_nav_link
tous naviguent par chronologie. Bien que je comprenne ce comportement par défaut, je ne comprends pas comment le modifier. J'ai trouvé qu'il correspond à adjacent_post_link dans link-template.php, mais puis il commence à sembler assez codé en dur. Est-il recommandé de réécrire cela à partir de zéro pour le remplacer, ou existe-t-il une meilleure solution.
Réponses:
Comprendre les internes
L'ordre de "tri" des articles adjacents (suivant / précédent) n'est pas vraiment un "ordre" de tri. Il s'agit d'une requête distincte sur chaque demande / page, mais elle trie la requête par le
post_date
- ou le parent du post si vous avez un post hiérarchique comme objet actuellement affiché.Lorsque vous jetez un œil aux composants internes de
next_post_link()
, vous voyez que c'est essentiellement un wrapper API pouradjacent_post_link()
. La dernière fonction appelle enget_adjacent_post()
interne avec l'$previous
argument / indicateur défini surbool(true|false)
pour saisir le lien de publication suivant ou précédent.Que filtrer?
Après avoir creusé plus profondément, vous verrez que le
get_adjacent_post()
lien source a de bons filtres pour sa sortie (alias résultat de la requête): (Nom du filtre / Arguments)"get_{$adjacent}_post_join"
"get_{$adjacent}_post_where"
"get_{$adjacent}_post_sort"
Vous pouvez donc en faire beaucoup . Cela commence par filtrer la
WHERE
clause, ainsi que laJOIN
table ed et l'ORDER BY
instruction.Le résultat est mis en cache en mémoire pour la demande actuelle, il n'ajoute donc pas de requêtes supplémentaires si vous appelez cette fonction plusieurs fois sur une seule page.
Création automatique de requêtes
Comme @StephenHarris l'a souligné dans les commentaires, il existe une fonction de base qui pourrait être utile lors de la construction de la requête SQL:
get_meta_sql()
- Exemples dans Codex . Fondamentalement, cette fonction est juste utilisée pour construire l'instruction meta SQL qui est utilisée dansWP_Query
, mais vous pouvez également l'utiliser dans ce cas (ou dans d'autres). L'argument que vous y jetez est un tableau, exactement le même que celui qui ajouterait à aWP_Query
.La valeur de retour est un tableau:
Vous pouvez donc utiliser
$sql['join']
et$sql['where']
dans votre rappel.Dépendances à garder à l'esprit
Dans votre cas, le plus simple serait de l'intercepter dans un petit plugin (mu) ou dans votre fichier themes functions.php et de le modifier en fonction de la
$adjacent = $previous ? 'previous' : 'next';
variable et de la$order = $previous ? 'DESC' : 'ASC';
variable:Les noms de filtre réels
Les noms des filtres sont donc:
get_previous_post_join
,get_next_post_join
get_previous_post_where
,get_next_post_where
get_previous_post_sort
,get_next_post_sort
Enveloppé comme un plugin
... et le rappel du filtre serait (par exemple) quelque chose comme ceci:
la source
get_meta_sql()
$meta_query
est tout simplement le tableau que vous passeriez àWP_Query
lameta_query
argument: Dans cet exemple:$meta_sql = get_meta_sql( $meta_query, 'post', $wpdb->posts, 'ID');
- cela génère laJOIN
et uneWHERE
partie de la requête qui doit être ajouté.La réponse de Kaiser est impressionnante et approfondie, mais il ne suffit pas de modifier la clause ORDER BY à moins que votre
menu_order
correspondance avec votre ordre chronologique.Je ne peux pas m'en attribuer le mérite, mais j'ai trouvé le code suivant dans cet essentiel :
J'ai modifié les noms de fonction pour WP.SE.
Si vous modifiez uniquement la clause ORDER BY, la requête recherche toujours les publications supérieures ou inférieures à la date de publication actuelle. Si vos articles ne sont pas classés par ordre chronologique, vous n'obtiendrez pas le bon article.
Cela modifie la clause where pour rechercher les publications dont le menu_order est supérieur ou inférieur à la menu_order du message actuel, en plus de modifier la clause orderby.
La clause orderby ne doit pas non plus être codée en dur pour utiliser DESC car elle devra changer selon que vous obtenez le lien de publication suivant ou précédent.
la source
WHERE
clause cherche'YYYY-mm-dd HH:mm:ss'
. Si cela n'est pas respecté, cela ne fonctionnera pas. Comme la valeur n'est pas définie par la base de données, mais par l'application, vous devrez d'abord vérifier ce format lors de la création de l'expression régulière.J'ai essayé de me connecter sans succès. Cela pourrait être juste un problème de ma configuration, mais pour ceux qui ne peuvent pas faire fonctionner le crochet, voici la solution la plus simple:
la source
get_previous_post_where
,get_previous_post_join
etget_previous_post_sort
de bien fonctionner avec les types de poste personnalisé et commande complexe qui comprend des touches méta, j'ai abandonné et utilisé cela. Merci!la source
Sur la base de la réponse de @Szabolcs Páll, j'ai créé cette classe d'utilité avec des méthodes d'assistance pour pouvoir obtenir des messages de type par ordre de menu et obtenir également le message suivant et précédent par ordre de menu. J'ai également ajouté des conditions pour vérifier si le message actuel est le premier ou le dernier message pour obtenir le dernier ou le premier message respectivement.
Par exemple:
La classe complète:
la source
Je trouve ce petit plugin vraiment pratique: http://wordpress.org/plugins/wp-query-powered-adjacent-post-link/
la source
Cela a fonctionné pour moi:
Tiré de: https://stackoverflow.com/questions/16495117/how-to-skip-certain-links-on-adjacent-posts-in-wordpress
la source
J'ai trouvé un moyen beaucoup plus facile de réaliser une navigation de post basée sur une méta-clé, sans avoir besoin de modifier functions.php.
Mon exemple: vous avez un products.php et vous souhaitez basculer entre les produits. Le produit précédent est le prochain moins cher, le prochain produit le prochain plus cher.
Voici ma solution pour single.php :
la source
query_posts
lorsque le codex indique qu'il ne doit pas être utilisé.WP_Query
doit être utilisé comme dans les réponses précédentes.