web-dev-qa-db-fra.com

Comment utiliser next_post_link et previous_post_link sur des publications uniques dans les résultats de recherche

J'utilise next_post_link et previous_post_link sur mes modèles de publication individuelle, pour naviguer d'une publication à l'autre, jusqu'à présent, tout va bien.

Mais si je fais une recherche et que je clique sur un message de résultat, le next_post_link ne m'emmène pas au message de résultat suivant, mais au message suivant dans l'ordre de publication par défaut.

Existe-t-il un moyen de faire en sorte que next_post_link et previous_post_link se comportent de différentes manières en fonction du contexte? Dans un contexte de recherche, parcourez uniquement les résultats de la recherche, etc.

EDIT: Je recherche une solution qui fonctionnerait avec des types de publication personnalisés.

3
mike23

S'appuyant sur la réponse de Bainternet ci-dessus, mais en le rendant plus générique, j'ai écrit ce plugin rapide. Vous pouvez probablement modifier la fonction de création de liens en bas pour faire ce que vous voulez plus précisément.

<?php 
/* 
Plugin Name: Search Context
Description: Use search context on single post pages when they're reached from a search results page to adjust the prev/next post links.
Author: Otto
*/

add_action('init','search_context_setup');
function search_context_setup() {
    global $wp;
    $wp->add_query_var('sq');

    add_filter('previous_post_link','search_context_previous_post_link');
    add_filter('next_post_link','search_context_next_post_link');

    if (is_search()) {
        add_filter('post_link','search_context_add_search_context');
    }   
}

function search_context_add_search_context($link) {
    $sq = get_search_query();
    if ( !empty( $sq ) )
        $link = add_query_arg( array( 'sq' => $sq ), $link );
    return $link;
}

function search_context_previous_post_link($link) {
    $sq = get_query_var('sq');
    if (empty($sq)) return $link;

    return get_search_context_adjacent_link($link, $sq, true);
}

function search_context_next_post_link($link) {
    $sq = get_query_var('sq');
    if (empty($sq)) return $link;
    return get_search_context_adjacent_link($link, $sq, false);
}

function get_search_context_adjacent_link($link, $sq, $previous) {
    global $post, $search_context_query;
    if ( !$post ) return $link;

    if (empty($search_context_query)) {
        $search_context_query = get_posts(array(
            'posts_per_page' => -1,
            'post_type' => 'post',
            'post_status' => 'publish',
            'fields' => 'ids',
            's' => $sq,
            )
        );
    }

    $key = array_search($post->ID, $search_context_query);

    if ($previous) $key--;
    else $key++;

    if (!isset($search_context_query[$key])) return '';

    $adjpost = get_post($search_context_query[$key]);

    $title = $previous ? 'Previous Post' : 'Next Post';
    $rel = $previous ? 'prev' : 'next';
    $permalink = add_query_arg( array( 'sq' => $sq ), get_permalink($adjpost) );

    $string = '<a href="'.$permalink.'" rel="'.$rel.'">';
    $output = $string . $title . '</a>';

    return $output;
}

Pour un type de publication personnalisé, vous devrez probablement remplacer le filtre "post_link" par un filtre "post_type_link". Vous devrez également ajuster la fonction pour vérifier le type de publication personnalisé. Ainsi:

...
if (is_search()) {
   add_filter('post_type_link','search_context_add_search_context',10,2);
}
...

et

function search_context_add_search_context($link, $post) {
    if ($post->post_type != 'YOUR-CUSTOM-TYPE') return $link;
    $sq = get_search_query();
    if ( !empty( $sq ) )
        $link = add_query_arg( array( 'sq' => $sq ), $link );
    return $link;
}

Dans la fonction get_search_context_adjacent_link, vous devrez également modifier la valeur post_type dans la requête.

7
Otto

Ce n’est pas ainsi que WordPress fonctionne: c’est-à-dire qu’une fois que vous avez entré un seul message parmi les résultats de la recherche, vous perdez le contexte de recherche et WordPress ne peut pas dire si vous êtes venu chercher les résultats de la recherche, une archive, une page de catégorie ou autre.

Le seul moyen auquel je puisse penser est de créer votre page de résultats de recherche personnalisée dans laquelle vous devez ajouter des paramètres au lien de publication unique qui contiendra la chaîne de requête de recherche et le numéro du résultat, par exemple:

$post_counter = 1;
while (have_posts()){
    the_post();
    ?>
    <a href="<?php echo add_query_arg( array('sq' => get_search_query(),'offset_number' =>$post_counter), get_permalink() ); ?>"><?php the_title(); ?></a>
    <?php
    $post_counter = $post_counter + 1;
}

puis dans votre fichier single.php où vous utilisez next_post_link et previous_post_link, vérifiez si vous avez obtenu les résultats de la recherche avant de l’imprimer et si vous avez créé une requête pour obtenir les bons liens, par exemple:

if (get_query_var('sq')){
    global $post;
    $temp = $post;
    //create a short query to get the right links based on search.
    $offset = (get_query_var('sq')) ? get_query_var('sq'): 0;
    $sq = get_posts(array(
        'posts_per_page' => 3, //we only need 3  PREVIOUS < this we know > NEXT
        'post_type' => 'post',
        'post_status' => 'published',
        's' => get_query_var('sq'), //this is to create a search query
        'offset', => $offset
    ));
    $counter = 0;

    foreach ($sq as $s){
        if ($offset == 0){ //this is the first result so no privous link should be printed only next
            if ($s->ID == $temp->ID){// look for current post as pivot
                $counter = $counter +1;
                if (isset ($sq[$counter])){
                    //next result exsits so we print it out
                    echo '<a href="'.add_query_arg( array('sq' => get_search_query(),'offset_number' =>($offset+1)), get_permalink($sq[$counter ]->ID) ).'">Next Post</a>';
                }
            }
        }else{
            if ($s->ID == $temp->ID){ // look for current post as pivot
                $counter = $counter - 1;
                if (isset ($sq[$counter])){
                    //Previous result exsits so we print it out
                    echo '<a href="'.add_query_arg( array('sq' => get_search_query(),'offset_number' =>($offset-1)), get_permalink($sq[$counter ]->ID) ).'">Previous Post</a>';
                }
                $counter = $counter + 2;
                if (isset ($sq[$counter])){
                    //next result exsits so we print it out
                    echo '<a href="'.add_query_arg( array('sq' => get_search_query(),'offset_number' =>($offset+1)), get_permalink($sq[$counter ]->ID) ).'">Next Post</a>';
                }
            }
        }
        $counter = $counter +1;
    }   

}else{
    //pring your regular links using next_post_link and previous_post_link
}

C'est désordonné et probablement pas le moyen le plus efficace de le faire, mais cela fonctionne.

1
Bainternet