J'ai 7 posts, comme ceci:
1
2
3
4 - c'est le poste actuel
5
6
7
Comme indiqué, le numéro quatre est la publication en cours d’affichage. J'ai besoin de créer une requête qui me permettra d'afficher les 3 articles précédents (par date de publication) et les trois articles suivants. Cela peut être fait avec deux requêtes distinctes.
J'ai pu afficher le post précédent ou suivant immédiatement, mais pas ceux plus bas/haut.
Des idées?
Cela peut être fait en une seule requête, bien que je ne puisse pas parler spécifiquement de la performance de cette requête (je n'ai pas dépensé beaucoup d'argent avec les requêtes de l'Union - je n'avais jamais eu besoin, jusqu'à maintenant) ..
Tout d'abord, une fonction permettant de sélectionner deux ensembles de résultats, mais en utilisant l'union pour les renvoyer sous la forme d'un ensemble de résultats unique.
function get_post_siblings( $limit = 3, $date = '' ) {
global $wpdb, $post;
if( empty( $date ) )
$date = $post->post_date;
//$date = '2009-06-20 12:00:00'; // test data
$limit = absint( $limit );
if( !$limit )
return;
$p = $wpdb->get_results( "
(
SELECT
p1.post_title,
p1.post_date,
p1.ID
FROM
$wpdb->posts p1
WHERE
p1.post_date < '$date' AND
p1.post_type = 'post' AND
p1.post_status = 'publish'
ORDER by
p1.post_date DESC
LIMIT
$limit
)
UNION
(
SELECT
p2.post_title,
p2.post_date,
p2.ID
FROM
$wpdb->posts p2
WHERE
p2.post_date > '$date' AND
p2.post_type = 'post' AND
p2.post_status = 'publish'
ORDER by
p2.post_date ASC
LIMIT
$limit
)
ORDER by post_date ASC
" );
$i = 0;
$adjacents = array();
for( $c = count($p); $i < $c; $i++ )
if( $i < $limit )
$adjacents['prev'][] = $p[$i];
else
$adjacents['next'][] = $p[$i];
return $adjacents;
}
Il y a une date de test, vous pouvez l'ignorer en toute sécurité ou ajouter votre propre valeur pour le test.
Voici un exemple de code que vous pouvez utiliser dans votre boucle single.php pour répertorier les résultats. Notez qu’il s’agit d’un exemple générique et que la fonction peut nécessiter la sélection de données supplémentaires J'ai indiqué que je ne savais pas exactement ce que vous vouliez. Par conséquent, voici un exemple et un exemple que vous pouvez utiliser pour tester les résultats.
<?php
$siblings = get_post_siblings( 3 ); // This is the same as doing the call below(which is just for illustration)
//$siblings = get_post_siblings( 3, $post->post_date );
$prev = $siblings['prev'];
foreach( $prev as $p )
echo get_the_time( 'd m Y', $p ) . ': ' . apply_filters( 'the_title', $p->post_title ) . '<br />';
$next = $siblings['next'];
foreach( $next as $p )
echo get_the_time( 'd m Y', $p ) . ': ' . apply_filters( 'the_title', $p->post_title ) . '<br />';
?>
En attente d'un retour... :)
Cela peut être fait beaucoup mieux avec la propriété date_query de la classe WP_Query. Cela permettra d'obtenir les publications avant la date de publication de la publication en cours.
// WP_Query arguments
$args = array (
'post_type' => 'post',
'post_status' => 'publish',
'date_query' => array(
'column' => 'post_date',
'before' => get_the_date()
),
);
// The Query
$the_query = new WP_Query( $args );
.........
3 x get_adjacent_post () :
global $post;
$current_post = $post; // remember the current post
for($i = 1; $i <= 3; $i++){
$post = get_previous_post(); // this uses $post->ID
setup_postdata($post);
// do your stuff here
the_title();
}
$post = $current_post; // restore
idem pour les 3 prochains articles, changez simplement la fonction pour get_next_post () ...
Pour ce faire avec une seule requête, tout en utilisant toujours l'API WP, essayez de remplacer la valeur LIMIT
par 3 dans les filtres get_previous_post_sort
ET get_next_post_sort
.
Comme JanFabry le suggère dans une réponse à @onetrickpony ci-dessus, vous pouvez modifier get_adjacent_post (). C'est ce que j'ai fait. Voici la fonction. J'ai changé la signature de la fonction parce que cela me semblait plus logique.
/**
* Retrieve multiple adjacent posts. Adapted from get_adjacent_post()
*
* Can either be next or previous post.
*
* @since 2.5.0
*
* @param int $post_id Optional. Will fall back to loop.
* @param int $limit Optional. Number of posts to return.
* @param bool $previous Optional. Whether to retrieve previous or next posts.
* @param bool $in_same_term Optional. Whether post should be in a same taxonomy term.
* @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
* @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'.
* @return mixed Array of post objects if successful. Null if global $post is not set. Empty string if no corresponding post exists.
*/
function pst_get_adjacent_posts( $post_id = null, $limit = 1, $previous = true, $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
global $wpdb;
if ( ( ! $post = get_post( $post_id ) ) || ! taxonomy_exists( $taxonomy ) )
return null;
$current_post_date = $post->post_date;
$join = '';
$posts_in_ex_terms_sql = '';
if ( $in_same_term || ! empty( $excluded_terms ) ) {
$join = " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id";
if ( $in_same_term ) {
if ( ! is_object_in_taxonomy( $post->post_type, $taxonomy ) )
return '';
$term_array = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
if ( ! $term_array || is_wp_error( $term_array ) )
return '';
$join .= $wpdb->prepare( " AND tt.taxonomy = %s AND tt.term_id IN (" . implode( ',', array_map( 'intval', $term_array ) ) . ")", $taxonomy );
}
$posts_in_ex_terms_sql = $wpdb->prepare( "AND tt.taxonomy = %s", $taxonomy );
if ( ! empty( $excluded_terms ) ) {
if ( ! is_array( $excluded_terms ) ) {
// back-compat, $excluded_terms used to be $excluded_terms with IDs separated by " and "
if ( false !== strpos( $excluded_terms, ' and ' ) ) {
_deprecated_argument( __FUNCTION__, '3.3', sprintf( __( 'Use commas instead of %s to separate excluded terms.' ), "'and'" ) );
$excluded_terms = explode( ' and ', $excluded_terms );
} else {
$excluded_terms = explode( ',', $excluded_terms );
}
}
$excluded_terms = array_map( 'intval', $excluded_terms );
if ( ! empty( $term_array ) ) {
$excluded_terms = array_diff( $excluded_terms, $term_array );
$posts_in_ex_terms_sql = '';
}
if ( ! empty( $excluded_terms ) ) {
$posts_in_ex_terms_sql = $wpdb->prepare( " AND tt.taxonomy = %s AND tt.term_id NOT IN (" . implode( $excluded_terms, ',' ) . ')', $taxonomy );
}
}
}
$adjacent = $previous ? 'previous' : 'next';
$op = $previous ? '<' : '>';
$order = $previous ? 'DESC' : 'ASC';
/**
* Filter the JOIN clause in the SQL for an adjacent post query.
*
* The dynamic portion of the hook name, $adjacent, refers to the type
* of adjacency, 'next' or 'previous'.
*
* @since 2.5.0
*
* @param string $join The JOIN clause in the SQL.
* @param bool $in_same_term Whether post should be in a same taxonomy term.
* @param array $excluded_terms Array of excluded term IDs.
*/
$join = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_term, $excluded_terms );
/**
* Filter the WHERE clause in the SQL for an adjacent post query.
*
* The dynamic portion of the hook name, $adjacent, refers to the type
* of adjacency, 'next' or 'previous'.
*
* @since 2.5.0
*
* @param string $where The WHERE clause in the SQL.
* @param bool $in_same_term Whether post should be in a same taxonomy term.
* @param array $excluded_terms Array of excluded term IDs.
*/
$where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' $posts_in_ex_terms_sql", $current_post_date, $post->post_type), $in_same_term, $excluded_terms );
/**
* Filter the ORDER BY clause in the SQL for an adjacent post query.
*
* The dynamic portion of the hook name, $adjacent, refers to the type
* of adjacency, 'next' or 'previous'.
*
* @since 2.5.0
*
* @param string $order_by The ORDER BY clause in the SQL.
*/
$sort = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT $limit" );
$query = "SELECT p.ID FROM $wpdb->posts AS p $join $where $sort";
$query_key = 'adjacent_post_' . md5( $query );
$result = wp_cache_get( $query_key, 'counts' );
if ( false !== $result ) {
if ( $result )
$result = array_map( 'get_post', $result );
return $result;
}
$result = $wpdb->get_col( $query );
if ( null === $result )
$result = '';
wp_cache_set( $query_key, $result, 'counts' );
if ( $result )
$result = array_map( 'get_post', $result );
return $result;
}