J'ai une page avec deux sections, chacune utilisant un WP_Query()
différent pour extraire events
name__, qui sont un type de publication personnalisé. Chaque WP_Query()
interroge un meta_key
pour la date de l'événement afin que la section 1 affiche uniquement le prochain events
et que la section 2 affiche le passé events
name__.
Le prochain events
de la section 1 affiche toutes les informations pertinentes sur ma page. Il est donc impossible de cliquer dessus.
Les events
passés de la section 2 affichent uniquement le titre event
et sont cliquables. Lorsque les utilisateurs cliquent sur un event
passé, ils sont liés à un modèle single-event.php
personnalisé pour le passé event
name__.
Je souhaite afficher la navigation Précédent/Suivant dans le modèle single-event.php
, mais la navigation ne doit pointer que vers le passé events
name__.
J'ai essayé d'utiliser next_post_link()
et previous_post_link()
, mais ceux-ci renverront également à la liste suivante events
name__, ce que je ne veux pas. Je peux probablement configurer une nouvelle WP_Query()
sur mon single-event.php
et la parcourir pour obtenir les ID Précédent/Suivant, mais répéter la requête semble être une étape radicale.
J'apprécierais vraiment un aperçu sur un moyen de filtrer les noms events
à venir de mes liens de post précédents/suivants. J'ai vu cette question mais je préférerais ne pas utiliser de plugin.
J'ai réussi à faire fonctionner cela en utilisant uniquement des filtres WordPress, grâce à l'indice de @ Milo.
Notez simplement que celles-ci sont assez spécifiques à mon cas mais vous ne devriez pas avoir de problème à les modifier pour votre propre usage. J'utilise des champs personnalisés avancés avec un champ Sélecteur de date appelé liens date
et Précédent/Suivant qui pointe uniquement vers les événements avec des champs date
définis sur n'importe quel jour avant aujourd'hui.
J'ai créé 5 filtres:
JOIN
(pour ajouter wp_postmeta
)WHERE
pour le lien précédentWHERE
pour le lien suivantSORT
pour le lien précédentSORT
pour le lien suivantVoici ce que j'ai trouvé, cela semble fonctionner, mais si quelqu'un découvre un problème, j'aimerais avoir des commentaires:
function get_adjacent_past_events_join($join) {
if(is_singular('event')) {
global $wpdb;
$new_join = $join."INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id ";
return $new_join;
}
return $join;
}
add_filter('get_previous_post_join', 'get_adjacent_past_events_join');
add_filter('get_next_post_join', 'get_adjacent_past_events_join');
function get_prev_past_events_where($where) {
if(is_singular('event')) {
global $wpdb, $post;
$id = $post->ID;
$current_event_date = get_field('date', $id);
$today = date('Ymd');
$new_where = "WHERE p.post_type = 'event' AND p.post_status = 'publish' AND (m.meta_key = 'date' AND (m.meta_key = 'date' AND CAST(m.meta_value AS CHAR) < '$today')) AND (m.meta_key = 'date' AND (m.meta_key = 'date' AND CAST(m.meta_value AS CHAR) < '$current_event_date'))";
return $new_where;
}
return $where;
}
add_filter('get_previous_post_where', 'get_prev_past_events_where');
function get_next_past_events_where($where) {
if(is_singular('event')) {
global $wpdb, $post;
$id = $post->ID;
$current_event_date = get_field('date', $id);
$today = date('Ymd');
$new_where = "WHERE p.post_type = 'event' AND p.post_status = 'publish' AND (m.meta_key = 'date' AND (m.meta_key = 'date' AND CAST(m.meta_value AS CHAR) < '$today')) AND (m.meta_key = 'date' AND (m.meta_key = 'date' AND CAST(m.meta_value AS CHAR) > '$current_event_date'))";
return $new_where;
}
return $where;
}
add_filter('get_next_post_where', 'get_next_past_events_where');
function get_prev_past_events_sort($sort) {
if(is_singular('event')) {
global $wpdb;
$new_sort = " GROUP BY p.ID ORDER BY m.meta_value+0 DESC";
return $new_sort;
}
return $sort;
}
add_filter('get_previous_post_sort', 'get_prev_past_events_sort');
function get_next_past_events_sort($sort) {
if(is_singular('event')) {
global $wpdb;
$new_sort = " GROUP BY p.ID ORDER BY m.meta_value+0 ASC";
return $new_sort;
}
return $sort;
}
add_filter('get_next_post_sort', 'get_next_past_events_sort');
j'ai eu un problème assez similaire, nécessaire pour trier et exclure plusieurs messages de navigation précédente/suivante. Le problème avec @ cfx La solution était: sa n'est pas capable pour ajax: la fonction is_singular()
renvoie false si vous chargez du contenu via wp-ajax. ainsi cela a fonctionné sur le chargement de page, mais pas, quand le contenu a été changé par ajax. global $post;
m'aidait ici.
voici ma solution:
/**
* WP: join postmeta to our sql query, so we can filter for custom fields
*
* @param $join
* @return string
*/
function jnz_adjacent_work_join( $join ) {
global $post;
if ( get_post_type( $post ) == 'work' ) {
global $wpdb;
return $join . "INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id ";
}
return $join;
}
add_filter('get_previous_post_join', 'jnz_adjacent_work_join');
add_filter('get_next_post_join', 'jnz_adjacent_work_join');
/**
* WP: Change order of post for prev / next navigation
* exclude posts with custom field "not_clickable" set to true
*
* @param $where
* @param $operator
* @return string|void
*/
function jnz_adjacent_work_where( $where, $operator ) {
global $post;
if ( get_post_type( $post ) == 'work' ) :
global $wpdb;
$where = $wpdb->prepare("WHERE p.post_title {$operator} '%s' AND p.post_type = 'work' AND p.post_status = 'publish' AND (m.meta_key = 'not_clickable' AND (m.meta_key = 'not_clickable' AND m.meta_value != 1))", $post->post_title );
endif;
return $where;
}
$gt = '<';
$lt = '>';
add_filter( 'get_next_post_where', function( $where ) use ( $lt ) {
return jnz_adjacent_work_where( $where, $lt );
});
add_filter( 'get_previous_post_where', function( $where ) use ( $gt ) {
return jnz_adjacent_work_where( $where, $gt );
});
dans ce cas, la requête de champ costum est la suivante: exclure tous les articles pour lesquels cf not_clickable
est défini sur true
.
un autre problème que j’ai rencontré: j’avais du contenu créé, puis implémenté ce champ personnalisé par la suite. La requête excluait donc également les publications qui n’avaient même pas ce champ attaché à la publication, que ce soit vrai ou faux. gardez cela à l’esprit lorsque vous utilisez ce type de filtrage. assurez-vous que chaque message a une valeur ou considérez-le dans votre syntaxe SQL.