J'ai une boucle personnalisée WP_Query
basée sur des variables meta_value:
$meta_cat = get_sub_field('category');
$posts = new WP_Query( array(
'cat' => $meta_cat,
'posts_per_page' => get_sub_field('recent_ppp'),
) );
Mais de toute façon, quand je vais faire un post collant, il n'est pas présenté comme le premier élément de la boucle while.
Je sais que ignore_sticky_posts
est défini par défaut sur false, je ne changerai donc pas. Également essayé de regarder dans order_by documentation si une valeur est liée à post-it mais ça ne l’est pas.
Bien que le order_by => 'post__in'
puisse être proche:
Conserver l'ordre de post-ID donné dans le tableau post__in
Mais quand je mets post__in => get_options('sticky_posts')
only le post collant est affiché.
Est-ce même possible sans créer deux boucles personnalisées (une pour gérer les posts collants et l'autre pour les autres posts? Ce serait vraiment dommage, car toutes les catégories ne contiennent pas de posts collants.
Si vous cherchez le code source dans lequel les stickies sont inclus, nous trouvons la condition suivante avant que WP_Query
continue d'inclure les posts collants
if ( $this->is_home
&& $page <= 1
&& is_array($sticky_posts)
&& !empty($sticky_posts)
&& !$q['ignore_sticky_posts']
) {
Le grand joueur est la condition is_home
. Les conditions à l'intérieur de WP_Query
sont définies en fonction des arguments qui lui sont transmis, et non de la page sur laquelle la requête est exécutée. Étant donné que vous transmettez cat
en tant qu'argument, is_home
sera défini sur false et is_category
sera défini sur true. Étant donné que is_home
est défini sur false, la condition ci-dessus échoue et les correctifs ne sont pas inclus.
Ce que nous pouvons faire est de définir manuellement is_home
sur true via pre_get_posts
. Tout ce que nous avons à faire est de passer 'wpse_is_home' => true,
à votre instance personnalisée WP_Query
Ensuite, nous exécutons notre action pre_get_posts
comme suit
add_action( 'pre_get_posts', function ( $q )
{
if ( true === $q->get( 'wpse_is_home' ) )
$q->is_home = true;
});
Nous voudrions probablement seulement montrer des notes qui sont pertinentes pour la catégorie interrogée. Dans ce cas, nous devrions supprimer les stickies n’appartenant pas à la catégorie spécifique interrogée.
Nous pouvons essayer ce qui suit, toujours dans notre action pre_get_posts
add_action( 'pre_get_posts', function ( $q )
{
remove_action( current_action(), __FUNCTION__ );
if ( true !== $q->get( 'wpse_is_home' ) )
return;
// Make sure get_sub_field exists, if not, bail
if ( !function_exists( 'get_sub_field' ) )
return;
// Lets query everything to keep code clean
$meta_cat = get_sub_field( 'category' ); // Copied from your code
$meta_cat = filter_var( $meta_cat, FILTER_VALIDATE_INT );
// Make sure we have a value, if not, bail
if ( !$meta_cat )
return;
$q->set( 'cat', $meta_cat );
// Set pagination if recent_ppp exists
$ppp = get_sub_field( 'recent_ppp');
$ppp = filter_var( $ppp, FILTER_VALIDATE_INT );
if ( $ppp )
$q->set( 'posts_per_page', $ppp );
// Set is_home to true
$q->is_home = true;
// Get all stickies
$stickies = get_option( 'sticky_posts' );
// Make sure we have stickies, if not, bail
if ( !$stickies )
return;
// Query the stickies according to category
$args = [
'post__in' => $stickies,
'posts_per_page' => -1,
'ignore_sticky_posts' => 1, // Ignore stickies
'cat' => $meta_cat,
'orderby' => 'post__in',
'order' => 'ASC',
'fields' => 'ids' // Get only post ID's
];
$valid_sticky_ids = get_posts( $args );
// Make sure we have valid ids
if ( !$valid_sticky_ids ) {
$q->set( 'post__not_in', $stickies );
return;
}
// Remove these ids from the sticky posts array
$invalid_ids = array_diff( $stickies, $valid_sticky_ids );
// Check if we still have ids left in $invalid_ids
if ( !$invalid_ids )
return;
// Lets remove these invalid ids from our query
$q->set( 'post__not_in', $invalid_ids );
});
Avant d'exécuter notre requête personnalisée, nous devons nous assurer que get_sub_field
existe et, plus important encore, que get_sub_field( 'category' )
est défini et valide. Cela évitera une défaillance catastrophique qui entraînera le retour de tous les messages, peu importe.
Votre WP_Query
peut ressembler à quelque chose comme ceci car nous n'avons besoin que de transmettre 'wpse_is_home' => true
:
if ( function_exists( 'get_sub_field' )
&& filter_var( get_sub_field( 'category' ), FILTER_VALIDATE_INT )
) {
$args = [
'wpse_is_home' => true
];
$posts_array = new WP_Query( $args ); // DO NOT USE $posts
// Run your loop as normal
}
DERNIÈRE MODIFICATION
Le code est testé et fonctionne comme prévu