web-dev-qa-db-ja.com

次/前の投稿リンクを使用して同じカテゴリの投稿を表示する

このコードを使用していますが、次の投稿/前の投稿のリンクをクリックすると、別のカテゴリの次の投稿/前の投稿にリダイレクトされます。

 previous_post_link( '%link', 'Prev post in category', $in_same_term = true );
 next_post_link( '%link', 'Next post in category', $in_same_term = true );

この記事 を使って問題を解決しようとしています。

これが私が投稿とカテゴリに使っているコードです、そして私はカスタム投稿タイプとカテゴリを使っていません:

$post_id = $post->ID;
$cat = get_the_category();
$current_cat_id = $cat[0]->cat_ID;
$args = array( 
    'category' => $current_cat_id, 
    'orderby'  => 'post_date', 
    'order'    => 'DESC' 
);
$posts = get_posts( $args );
foreach( $posts as $post ) {
    echo $post->post_content;
}
previous_post_link( '%link', 'Prev post in category', $in_same_term = true );
next_post_link( '%link', 'Next post in category', $in_same_term = true );

基本的にはカテゴリに基づいてすべての投稿を取得しているので、今度は次の投稿/前の投稿のリンクをこの特定のカテゴリに対してのみ機能させます。

7
user54318

これは、投稿のカテゴリベースの前後のリンクを取得するためのコードです。

<?php
$post_id = $post->ID; // current post ID
$cat = get_the_category(); 
$current_cat_id = $cat[0]->cat_ID; // current category ID 

$args = array( 
    'category' => $current_cat_id,
    'orderby'  => 'post_date',
    'order'    => 'DESC'
);
$posts = get_posts( $args );
// get IDs of posts retrieved from get_posts
$ids = array();
foreach ( $posts as $thepost ) {
    $ids[] = $thepost->ID;
}
// get and echo previous and next post in the same category
$thisindex = array_search( $post_id, $ids );
$previd    = isset( $ids[ $thisindex - 1 ] ) ? $ids[ $thisindex - 1 ] : 0;
$nextid    = isset( $ids[ $thisindex + 1 ] ) ? $ids[ $thisindex + 1 ] : 0;

if ( $previd ) {
    ?><a rel="prev" href="<?php echo get_permalink($previd) ?>">Previous</a><?php
}
if ( $nextid ) {
    ?><a rel="next" href="<?php echo get_permalink($nextid) ?>">Next</a><?php
}
16
user54318

previous_post_linknext_post_link の両方の関数には5つのパラメータがあります。$format:リンクの前後にあるものを制御するために使用されるフォーマット文字列
$link:表示へのリンクテキスト
$in_same_term:次/前の投稿が現在の投稿と同じ分類用語に属している必要があるかどうか
$excluded_terms:投稿を除外する条件$taxonomy$in_same_termがtrueの場合に使用する分類法お分かりのように、$in_same_termパラメータはまさにあなたが必要としていることを行います。ただし、サンプルコードでは正しく使用されていません。あなたは実際にtrueを変数$in_same_termに代入した結果を渡しています。これはうまくいきません。引数を渡すのは、値を渡すのと同じくらい簡単です。

previous_post_link( '%link', 'Prev post in category', true );
next_post_link( '%link', 'Next post in category', true );

編集: (OPが質問を更新した後に編集)問題は、previous_post_linknext_post_linkがグローバルな投稿オブジェクトを使用していることです。これを防ぐには、$posts-ループ内で$singlepostなどの別の変数名を使用します。

foreach ( $posts as $singlepost ) {
    echo $singlepost->post_content
}

この方法で、グローバルな$postオブジェクトは保持されます。別の方法として、グローバルなpostオブジェクトを一時変数に格納し、後で$postを再設定することもできますが、それはsetup_postdataを呼び出す場合にのみ必要です(そうではありません)。

3
engelen

構文エラーがあることを除けば、あなたのコードは私にとって意味がありません。あなたのコードが立っているように、あなたが投稿/ブログページから投稿をクリックすると、あなたはそれがあるべきように投稿の単一のビューに連れて行かれます。その投稿のみがsingle.phpに表示されます。

問題は投稿リンクをクリックしたときに始まります。それが前の投稿であるか次の投稿であるかは関係ありません。次/前のページが読み込まれたときに返されるのは、その特定のカテゴリ内のすべての投稿です。そういうわけであなたはあなたのsingle.phpをどのようにコーディングしたか、そしてあなたの投稿リンクがあなたがそれを期待するように働かないのはなぜか。

Single.phpページでループを設定するのにget_posts()を使用しません。通常の適切なループを使用します。 テーマ開発について/のコーデックスでこのページをチェックしてください

これは期待通りに動作するsingle.phpの例です。

<?php
get_header(); ?>

<div id="main-content" class="main-content">

    <div id="primary" class="content-area">
        <div id="content" class="site-content" role="main">
            <?php
                // Start the Loop.
                while ( have_posts() ) : the_post(); ?>

            <?php
                    get_template_part( 'content', get_post_format() );

                    // Previous/next post navigation.
                    previous_post_link( '%link', 'Prev post in category', true );
                    next_post_link( '%link', 'Next post in category', true );

                    // If comments are open or we have at least one comment, load up the comment template.
                    if ( comments_open() || get_comments_number() ) {
                        comments_template();
                    }
                endwhile;
            ?>
        </div><!-- #content -->
    </div><!-- #primary -->

<?php get_sidebar( 'content' ); ?>
</div><!-- #main-content -->

<?php
get_footer();

他の答えで指摘されているように、 next_post_linkprevious_post_link の使い方について読んでください。

1
Pieter Goosen

私は、カスタム投稿タイプとカスタム分類法のために、それらすべてを必要とする同じ問題を抱えていました。 user54318は私を正しい方向に向けさせました、それはcpt'sを実行することができないので、私もここで私の結果を共有するつもりです:

//get custom taxonomies.
$terms = wp_get_post_terms( get_the_ID(), 'product_cat' ); //last argument is the custom taxonomy. change to desired tax
//run through all terms and filter out the one, that i need. 
$stay_in = array();
foreach( $terms as $term ) :
/*this loop looks for a category, that is a children of category id 37. change to your needs. 
only importance is to build an array of term ids, to be included in the previous/next behaviour, so if you already know your ids, you could also use something like $stay_in = array( 43 ); and skip this whole loop..*/
    if ( $term->parent == 37 ) :
        $stay_in[] = $term->term_id;
        break; //break out the foreach, if found.
    endif;
endforeach;
//get all post ids, that are in my defined category
$args = array(
    'post_type'         => 'product', //custom post type
    'posts_per_page'    => -1,
    'tax_query'         => array(
        array(
            'taxonomy'  => 'product_cat', // custom taxonomy
            'field'     => 'term_id',
            'terms'     => $stay_in,
            'operator'  => 'IN', //change to your needs.. IN, NOT IN, AND, EXISTS, NOT EXISTS
        )
    ),
    'orderby'           => 'post_date',
    'order'             => 'ASC',
    'fields'            => 'ids', //only return the post ids, not the whole post-objects
);
$all_posts = new WP_Query( $args );
//search for the current post by its id and look for the previous / next ids
$this_index = array_search( $post->ID, $all_posts->posts );
$prev_id = $all_posts->posts[ $this_index - 1 ];
$next_id = $all_posts->posts[ $this_index + 1 ];
//echo links, if prevoius/next exists
if ( ! empty( $prev_id ) ) :
    echo '<a rel="prev" href="' . get_permalink( $prev_id ) . '">' . __( 'previous', 'your_theme_text_domain' ) . '</a>';
endif;

if ( ! empty( $next_id ) ) :
    echo '<a rel="next" href="' . get_permalink( $next_id ) . '">' . __( 'next', 'your_theme_text_domain' ) . '</a>';
endif;
wp_reset_postdata();
0
honk31