web-dev-qa-db-ja.com

検索結果の単一の投稿でnext_post_linkとprevious_post_linkを使用する方法

私は私の単一の投稿テンプレートでnext_post_linkprevious_post_linkを使って投稿から投稿へ移動しています。

しかし、検索を実行して結果投稿をクリックした場合、next_post_linkは次の結果投稿に移動するのではなく、デフォルトの投稿順で次の投稿に移動します。

状況に応じてnext_post_linkprevious_post_linkを異なる方法で動作させる方法はありますか?検索コンテキストでは、検索結果内のみを閲覧するなど.

EDIT:カスタム投稿タイプで機能する解決策を探しています。

3
mike23

上記のBainternetの答えを基にしていますが、より一般的にして、このクイックプラグインを書きました。あなたはおそらくあなたがもっと正確に欲しいものをするために一番下のリンク構築機能を修正することができます。

<?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;
}

カスタム投稿タイプの場合は、おそらく 'post_link'フィルタを 'post_type_link'フィルタに変更する必要があります。カスタム投稿タイプを確認するには、機能を調整する必要もあります。そのようです:

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

そして

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;
}

Get_search_context_adjacent_link関数の下の方で、クエリのpost_typeの値もそこで変更する必要があります。

7
Otto

これはWordPressの動作方法ではありません。つまり、検索結果から単一の投稿を入力すると検索コンテキストが失われ、WordPressは検索結果、アーカイブ、カテゴリページなどを検索したかどうかを判断できません。

私がパスで考えることができる唯一の方法はあなたが検索クエリ文字列と結果の番号を保持する単一の投稿リンクにパラメータを追加するべきあなたのカスタム検索結果ページを作成することです:

$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;
}

次に、next_post_linkprevious_post_linkを使用するsingle.phpファイルで、印刷する前にフォームの検索結果が表示されたかどうかを確認し、正しいリンクを取得するためのクエリを作成したかどうかを確認します。

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
}

それは面倒で、おそらくそれを行うための最も効率的な方法ではありませんが、うまくいきます。

1
Bainternet