Comment retourner les résultats d'un get_posts () afin explicitement défini
-
16-10-2019 - |
Question
Je suis en train de créer une boucle de messages explicity a ordonné, par exemple:
<?php $args = array(
'include' => '1,3,8,4,12' ); ?>
<?php get_posts( $args ); ?>
Les résultats sont triés par date par défaut, et il n'y a pas d'option orderby pour retourner les messages dans l'ordre où ils ont été introduits. Il y a eu plusieurs demandes bug / fonctionnalité posté à ce sujet dans Trac, mais jusqu'à présent, pas de chance. J'ai déconné autour dans le noyau des fichiers un peu, mais ne l'ai pas obtenu partout avec elle.
Quelqu'un peut-il proposer une solution de contournement pour ce comportement?
Cordialement, Dalton
La solution
D'accord, je suis déterminé à trouver un moyen de le faire, et je pense que je l'ai. Je l'avais espéré trouver une solution plus simple et éviter d'avoir à utiliser un nouvel objet WP_Query, mais il est trop ancrée dans le fonctionnement de la boucle. Tout d'abord, nous avons deux fonctions utilitaires:
// Set post menu order based on our list
function set_include_order(&$query, $list) {
// Map post ID to its order in the list:
$map = array_flip($list);
// Set menu_order according to the list
foreach ($query->posts as &$post) {
if (isset($map[$post->ID])) {
$post->menu_order = $map[$post->ID];
}
}
}
// Sort posts by $post->menu_order.
function menu_order_sort($a, $b) {
if ($a->menu_order == $b->menu_order) {
return 0;
}
return ($a->menu_order < $b->menu_order) ? -1 : 1;
}
Ceux-ci nous permettra de définir la propriété de menu_order
en fonction de notre propre liste, et puis trier les messages dans un objet de requête sur cette base.
Voici comment trier les requêtes et messages:
$plist = array(21, 43, 8, 44, 12);
$args = array(
'post_type' => 'attachment',
'post_status' => 'any',
'post__in' => $plist
);
// Create a new query
$myquery = new WP_Query($args);
// set the menu_order
set_include_order($myquery, $plist);
// and actually sort the posts in our query
usort($myquery->posts, 'menu_order_sort');
Alors maintenant, nous avons notre propre objet de requête, et la $myquery->posts
est triée selon notre fonction menu_order_sort
personnalisée. La seule partie délicate maintenant, est que nous devons construire notre boucle en utilisant notre objet de requête personnalisée:
while($myquery->have_posts()) : $myquery->the_post();
?>
<div><a id="post_id_<?php the_ID(); ?>" class="nb" href="<?php the_permalink(); ?>"><?php the_title(); ?></a> Post ID: <?php the_ID(); ?>
</div>
<?php
endwhile;
wp_reset_postdata();
De toute évidence, vous voulez corriger le code du modèle en boucle là.
J'espérais trouver une solution qui ne nécessite pas l'utilisation d'un objet de requête personnalisée, peut-être à l'aide query_posts()
et le remplacement de la propery de posts
sur la $wp_query
mondiale, mais je ne pouvais pas le faire fonctionner à droite. Avec un peu plus de temps pour travailler, qui aurait pu être faisable.
De toute façon, voyez si cela vous où vous devez aller?
Autres conseils
Vous pouvez essayer ceci:
add_filter('posts_orderby', 'enforce_specific_order');
$posts = get_posts($args);
remove_filter( current_filter(), __FUNCTION__ );
function enforce_specific_order($orderby) {
global $wpdb;
return "FIND_IN_SET(".$wpdb->posts.".ID, '1,3,8,4,12') ASC";
}
Je pense que c'est le meilleur moyen de rendre les résultats d'une get_posts dans un ordre défini. Et en plus de cela, il est une solution native, sans hacks
<?php
$posts_order = array('1,3,8,4,12');
$args = array(
'post__in' => $posts_order,
'orderby' => 'post__in'
);
get_posts( $args );
?>
de WordPress 3.5, cette fonctionnalité est maintenant dans le noyau. Vous pouvez commander explicitement les messages en utilisant le paramètre « post__in ». http://core.trac.wordpress.org/ticket/13729
Qu'en est-il juste le orderby
de compensation avec un filtre? Juste avant vous interrogez vos messages, mis en:
add_filter('posts_orderby', '__return_false');
Alors, après la boucle se fait:
remove_filter('posts_orderby', '__return_false');
La raison de la suppression du filtre est de nouveau si vous avez d'autres boucles sur la page (par exemple de widgets) qui auront besoin de leur commande explicite normal.