サポート » 使い方全般 » 投稿ページの前後移動 カテゴリで変更する

  • 解決済 bujin450

    (@bujin450)


    色々と検索しても適切な事例が見つからないため、こちらで質問いたします。
    当方テーマのカスタマイズ、自作テーマが作成できる程度のスキルです。

    一覧から投稿記事に移動した場合、投稿記事に複数のカテゴリが設定してある場合
    状況によって、カテゴリ間の移動を変更したいと考えています。
    少々わかりにくいので、以下にまとめます。

    ●前提
    カテゴリ構成

    親カテゴリA
     子カテゴリB
     子カテゴリC

    ●できているもの

    固定ページAで親カテゴリAの一覧(全部の記事)を表示し
    一覧から個別の投稿記事を表示したときに
    子カテゴリB、Cの区別なく前後の投稿に移動したい
    ⇒これはできています

    ●作りたいもの

    固定ページBで子カテゴリBのみの一覧を表示した場合
    一覧から個別の投稿記事を表示したときに
    子カテゴリBのみの前後投稿に移動したい
    ※Cも同様

    まず、こういった処理は可能なのでしょうか?
    もし可能であれば、なんらかのヒントを頂けると大変助かります。

    どうぞよろしくお願いします。

15件の返信を表示中 - 1 - 15件目 (全15件中)
  • これって、違うリンク元でリンク先での挙動を変えるということですか?

    親カテゴリで記事一覧リンクから、どれか投稿記事を表示した場合は、その前後ページ移動は親カテゴリ内で行い

    子カテゴリの記事一覧リンクから、どれか投稿記事を表示した場合は、その前後ページ移動はその子カテゴリ内で行いたいのです。

    以下、図示してみました。
    伝わりますでしょうか。

    https://drive.google.com/file/d/0B0mnnjAmN1cObjUxcWhjYlg0WXc/view?usp=sharing

    図のどちらか一方はできるのですが、両方の共存ができなくて困っています。

    試してないのでできるかどうかわかりませんが、
    以下の記事が参考になるのではないでしょうか。

    こちらの記事を使って、どこからのリンクかを判定してページのリンクを出し分けて、
    リンク元(参照元)のURLで条件分岐をする方法

    こちらの記事で子カテゴリBのみの前後投稿のリンクを出力
    テンプレートタグ/previous post link

    参考まで。

    有益なヒントありがとうございます!

    すぐに作業ができないのですが、試してみて改めてお知らせします。

    取り急ぎお礼まで。

    お返事おそくなりました。

    頂いたヒントで試してみましたが、結論から言うとダメでした。

    URLにカテゴリ名を表示するようにパーマリンクを設定してURLに含まれるカテゴリ名で前後のナビゲーション表示を切り替える様考えました。

    カテゴリ一覧からの最初の表示は意図した通りなのですが、次のページはURLにカテゴリ名が表示されるので、全部を通して表示したい場合はできなくなってしまいました(当たり前ですね。。)

    参考までにコードを記します。※一部略

    <?php $url = $_SERVER['REQUEST_URI']; ?>
    <?php if(strstr($url,'カテゴリー名')): ?>
     <span class="next-post"><?php next_post_link('%link ', '<img src="~略>', true ); ?></span>
     <span class="prev-post"><?php previous_post_link(' %link', '<img src="~略">', true ); ?></span>
    
    <?php else: ?>
     <span class="next-post"><?php next_post_link('%link ', '<img src="~略 ">', false ); ?></span>
     <span class="prev-post"><?php previous_post_link('%link', '<img src="h~略 ">', false); ?></span>
    <?php endif; ?>


    さらに検索したところ、同じ問題を解決した方がいましたので、参考にこちらのコードを利用させてもらったのですが、上手く動作しませんでした。

    http://mekemoke.jp/2014/01/1344.html

    コードを追っているのですが、知識不足で問題点が見つかっていません。

    取り急ぎ現時点での状況を報告しました。

    引き続きよろしくお願い致します。

    わたしもいろいろ考えてみたのですが、
    固定ページAあるいはBから個別記事へのリンクの条件分岐は、

    $_SERVER['HTTP_REFERER']

    でできると思うのですが、その後、子カテゴリがもともとAからなのかBからなのか判断させる条件分岐もないとダメだということに気づきました。
    で、例えば、
    リンクの後ろに ?test=a あるいは、 ?test=b として、

    $_GET['test']

    で条件判定すればいいような気がします。
    (もっといい方法があるかもしれませんが)

    この二つが両立できるような条件判定ができればいいような?

    個別には機能できることは確認できたのですが、
    両立する方法は試せていません。

    一応、参考まで。

    こんにちは

    カテゴリー ID を URL パラメーター(catid)で指定し、下記のようにナビゲーションをカスタマイズするのではどうでしょうか。

    function my_get_adjacent_post_by_terms( $terms = '', $previous = true, $taxonomy = 'category' ) {
    	global $wpdb;
    
    	if ( ( !$post = get_post() ) || !taxonomy_exists( $taxonomy ) || !is_object_in_taxonomy( $post->post_type, $taxonomy ) )
    		return '';
    
    	$join = '';
    	$where = '';
    
    	if ( !empty( $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";
    		$where .= $wpdb->prepare( "AND tt.taxonomy = %s AND tt.term_id IN (%s)", $taxonomy, implode( ',', $terms ) );
    	}
    
    	$where .= " AND p.post_status='publish'";
    
    	$op = $previous ? '<' : '>';
    	$where = $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s $where", $post->post_date, $post->post_type );
    
    	$order = $previous ? 'DESC' : 'ASC';
    	$sort = "ORDER BY p.post_date $order LIMIT 1";
    
    	$result = $wpdb->get_var( "SELECT p.ID FROM $wpdb->posts AS p $join $where $sort" );
    
    	if ( null === $result )
    		$result = '';
    	if ( $result )
    		$result = get_post( $result );
    
    	return $result;
    }
    
    function my_pagination_post_link( $output, $format, $link, $post, $adjacent) {
    	if ( $post->post_type === 'post' && isset( $_GET['catid'] ) && is_numeric( $_GET['catid'] ) ) {
    		$catid = intval( $_GET['catid'] );
    
    		$categories = get_the_category();
    		$excluded_cats = array();
    		foreach( $categories as $category ) {
    			if ( $category->cat_ID !== $catid ) {
    				$excluded_cats[] = $category->cat_ID;
    			}
    		}
    
    		$post = my_get_adjacent_post_by_terms( array( $catid ), $adjacent == 'previous' );
    		if ( !$post ) {
    			$output = '';
    		} else {
    			$title = $post->post_title;
    			if ( empty( $post->post_title ) )
    				$title = $previous ? __( 'Previous Post' ) : __( 'Next Post' );
    
    			$title = apply_filters( 'the_title', $title, $post->ID );
    
    			$date = mysql2date( get_option( 'date_format' ), $post->post_date );
    			$rel = $previous ? 'prev' : 'next';
    
    			$string = '<a href="' . get_permalink( $post ) . "?catid={$catid}" . '" rel="'.$rel.'">';
    			$inlink = str_replace( '%title', $title, $link );
    			$inlink = str_replace( '%date', $date, $inlink );
    			$inlink = $string . $inlink . '</a>';
    
    			$output = str_replace( '%link', $inlink, $format );
    		}
    	}
    	return $output;
    }
    add_filter( 'previous_post_link', 'my_pagination_post_link', 10, 5 );
    add_filter( 'next_post_link', 'my_pagination_post_link', 10, 5 );

    ioxrxogi 様

    お返事、その後の検討ありがとうございます。

    ishitaka 様

    コードを書いていただきありがとうございます!

    こちらをfunctions.phpに記述するとして、single.phpではどのように記述すればよいのでしょうか。
    今一つ理解できていませんので、もう少しご教授いただけると助かります。

    どうぞよろしくお願いします。

    そのまま、the_post_navigation 関数等の標準のナビゲーションを使用してください。

    例)

    the_post_navigation( array(
    	'prev_text' => '<span class="screen-reader-text">過去の投稿</span><span aria-hidden="true" class="nav-subtitle">前</span> <span class="nav-title"><span class="nav-title-icon-wrapper"><</span>%title</span>',
    	'next_text' => '<span class="screen-reader-text">次の投稿</span><span aria-hidden="true" class="nav-subtitle">次</span> <span class="nav-title">%title<span class="nav-title-icon-wrapper">></span></span>',
    ) );

    ありがとうございます。

    ワードプレスサイトに組み込んでみました。
    記事の前後移動のナビゲーションは表示されていますが、全カテゴリが表示されてしまい、表示されているページのカテゴリが次のページに継承されていない状態です。

    何か設定をする必要があるのでしょうか。
    質問ばかりで恐縮です。

    固定ページ B で子カテゴリ B のみの一覧の場合を例にすると、
    一覧を出力するループ内で、
    <a href="<?php the_permalink() ?>"><?php the_title(); ?></a>
    のような、記述をしている場合、
    <a href="<?php the_permalink() ?>?catid=123"><?php the_title(); ?></a>
    のように、子カテゴリー B の ID (例では、123)を、URL パラメーターで追加してください。

    なお、コードは検証していませんので内容を理解した上で使用してください。多少の手直しは必要かもしれません。

    • この返信は2年、 7ヶ月前にishitakaが編集しました。

    お返事遅くなりました。
    大変お世話になりました。
    うまく動作しました!

    今回のパターンのように複数カテゴリに属する投稿ページを異なるカテゴリ一覧から表示し、同じカテゴリ内での移動は需要がありそうな気がしますが、例を見かけませんでした。

    私のようにあまりプログラムに慣れていない人でも扱えるように(これはこれで問題もありますが)以下に手順をまとめておきます。※長いです。

    【手順】

    1.functions.phpにコードを記述
    2.固定ページテンプレート page-xxx.php の投稿ページへのリンクでIDを付与
    3.投稿ページテンプレート single-xxx.php にリンクのコードを記述

    1.functions.phpにコードを記述

    function my_get_adjacent_post_by_terms( $terms = '', $previous = true, $taxonomy = 'category' ) {
        global $wpdb;
    
        if ( ( !$post = get_post() ) || !taxonomy_exists( $taxonomy ) || !is_object_in_taxonomy( $post->post_type, $taxonomy ) )
            return '';
    
        $join = '';
        $where = '';
    
        if ( !empty( $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";
            $where .= $wpdb->prepare( "AND tt.taxonomy = %s AND tt.term_id IN (%s)", $taxonomy, implode( ',', $terms ) );
        }
    
        $where .= " AND p.post_status='publish'";
    
        $op = $previous ? '<' : '>';
        $where = $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s $where", $post->post_date, $post->post_type );
    
        $order = $previous ? 'DESC' : 'ASC';
        $sort = "ORDER BY p.post_date $order LIMIT 1";
    
        $result = $wpdb->get_var( "SELECT p.ID FROM $wpdb->posts AS p $join $where $sort" );
    
        if ( null === $result )
            $result = '';
        if ( $result )
            $result = get_post( $result );
    
        return $result;
    }
    
    function my_pagination_post_link( $output, $format, $link, $post, $adjacent) {
        if ( $post->post_type === 'post' && isset( $_GET['catid'] ) && is_numeric( $_GET['catid'] ) ) {
            $catid = intval( $_GET['catid'] );
    
            $categories = get_the_category();
            $excluded_cats = array();
            foreach( $categories as $category ) {
                if ( $category->cat_ID !== $catid ) {
                    $excluded_cats[] = $category->cat_ID;
                }
            }
    
            $post = my_get_adjacent_post_by_terms( array( $catid ), $adjacent == 'previous' );
            if ( !$post ) {
                $output = '';
            } else {
                $title = $post->post_title;
                if ( empty( $post->post_title ) )
                    $title = $previous ? __( 'Previous Post' ) : __( 'Next Post' );
    
                $title = apply_filters( 'the_title', $title, $post->ID );
    
                $date = mysql2date( get_option( 'date_format' ), $post->post_date );
                $rel = $previous ? 'prev' : 'next';
    
                $string = '<a href="' . get_permalink( $post ) . "?catid={$catid}" . '" rel="'.$rel.'">';
                $inlink = str_replace( '%title', $title, $link );
                $inlink = str_replace( '%date', $date, $inlink );
                $inlink = $string . $inlink . '</a>';
    
                $output = str_replace( '%link', $inlink, $format );
            }
        }
        return $output;
    }
    add_filter( 'previous_post_link', 'my_pagination_post_link', 10, 5 );
    add_filter( 'next_post_link', 'my_pagination_post_link', 10, 5 );

    2.固定ページテンプレート page-xxx.php の投稿ページへのリンクでIDを付与

    ループ内の記述
    通常 

    <a href="<?php the_permalink() ?>"><?php the_title(); ?></a> 
    のところを

    <a href="<?php the_permalink() ?>?catid=123"><?php the_title(); ?></a>
    のようにカテゴリIDをURLパラメータで追加(123の部分を書換)

    3.投稿ページテンプレート single-xxx.php にリンクのコードを記述

    <?php
    the_post_navigation( array(
        'prev_text' => '<span class="screen-reader-text">過去の投稿</span><span aria-hidden="true" class="nav-subtitle">前</span> <span class="nav-title"><span class="nav-title-icon-wrapper"><</span>%title</span>',
        'next_text' => '<span class="screen-reader-text">次の投稿</span><span aria-hidden="true" class="nav-subtitle">次</span> <span class="nav-title">%title<span class="nav-title-icon-wrapper">></span></span>',
    ) );
    ?>

    以上です

    bujin450 さん、まとめてもらい有難うございます。
    私の説明はちょっと不親切でしたね。(^^

    あと、訂正です。
    動作に関係のない無駄なコードが思い切り入っていました。
    別の方法を模索していたときのコードを消し忘れました。

    my_pagination_post_link 関数を下記のコードに差し替えてください。

    function my_pagination_post_link( $output, $format, $link, $post, $adjacent) {
    	if ( $post->post_type === 'post' && isset( $_GET['catid'] ) && is_numeric( $_GET['catid'] ) ) {
    		$catid = intval( $_GET['catid'] );
    
    		$post = my_get_adjacent_post_by_terms( array( $catid ), $adjacent == 'previous' );
    		if ( !$post ) {
    			$output = '';
    		} else {
    			$title = $post->post_title;
    			if ( empty( $post->post_title ) )
    				$title = $previous ? __( 'Previous Post' ) : __( 'Next Post' );
    
    			$title = apply_filters( 'the_title', $title, $post->ID );
    
    			$date = mysql2date( get_option( 'date_format' ), $post->post_date );
    			$rel = $previous ? 'prev' : 'next';
    
    			$string = '<a href="' . get_permalink( $post ) . "?catid={$catid}" . '" rel="'.$rel.'">';
    			$inlink = str_replace( '%title', $title, $link );
    			$inlink = str_replace( '%date', $date, $inlink );
    			$inlink = $string . $inlink . '</a>';
    
    			$output = str_replace( '%link', $inlink, $format );
    		}
    	}
    	return $output;
    }
    • この返信は2年、 7ヶ月前にishitakaが編集しました。

    ishitaka様

    ご丁寧な対応ありがとうございます。
    新しいコードを組み込んで動作を確認しました。

    いろいろとありがとうございました。

    本当に助かりました。解決済みにいたします。

    • この返信は2年、 7ヶ月前にbujin450が編集しました。
15件の返信を表示中 - 1 - 15件目 (全15件中)
  • トピック「投稿ページの前後移動 カテゴリで変更する」には新たに返信することはできません。