サポート » 使い方全般 » 複数カテゴリに所属する子カテゴリー内の記事の扱い

  • 解決済 kujira123

    (@kujira123)


    はじめまして。いつも勉強させてもらっています。
    タイトルの通りの内容で詰まってしまいましたので、アドバイスをお願い致します。
    自分の頭の中を整理するためにも、ケースを単調化して珍妙な例えをしますが…

    「コウモリ」というカテゴリー中に数百の記事があります。
    この「コウモリ」は「鳥」と「獣」の二つの親カテゴリーに所属しています。

    その「コウモリ」内の記事を表示するとき、「鳥」カテゴリの孫として呼び出したときと
    「獣」の孫として呼び出したときのスタイルやメニュー内容を変えたいのです。

    現状ですと、様々な条件分岐で「鳥」と「獣」の両方に反応してしまうか、
    逆にID番号の若い「鳥」が勝ち、分岐にならない状況になります。

    「鳥」としての表示の時は「鳥」、「獣」の時は「獣」のナビボタンの色を変更したい場合、
    親IDで分岐を図ると、どちらのボタンも色が変わってしまいます(考えてみれば当たり前ですが…)。

    逆に、previous_post_linkで「前の記事」のリンクを呼び出したときは、
    現時点で「獣>>コウモリ」カテゴリ内の記事であっても、「鳥>>コウモリ」内の
    前の記事へとばされたりします。
    同じく、カテゴリ内の記事一覧リンクも、すべて「鳥>>コウモリ」の方の記事へリンクされてしまいます。

    非常に単純明快な現象ですので、あっさり解決するかと思い取り掛かってみたのですが、
    何か見落としているのか、どうしてもうまくいきません。
    皆様のお知恵を拝借できれば幸いです。

9件の返信を表示中 - 1 - 9件目 (全9件中)
  • モデレーター jim912

    (@jim912)

    kujira123さん、こんにちは。

    まず、大前提として、WordPressのデフォルトでは、投稿は複数のカテゴリーに属することは可能ですが、カテゴリーは複数の親カテゴリーを持つことはできないはずです。ご自身の設定とサイト構成を確認してください。

    投稿が複数のカテゴリーに属している場合の話としてですが、そう簡単な話ではありません。
    まず、希望する内容を実現するには、遷移元がどこかを取得しなければなりません。WordPress自体には、この機能はありませんから、独自に実装する必要があります。(リファラー、cookieへの保存、セッションの実装、リンクへのパラメータ付加など)
    それから、遷移元がカテゴリーでなかった場合(トップ、年月アーカイブ、タグ、著者)からの遷移の場合をどうするかも考えなければなりません。
    それと、前後記事のリンクは、おそらく独自の関数実装が必要と思われます。

    投稿を複数のカテゴリーに属させるのではなく、同一内容の投稿(もしくは1つの投稿のエイリアスとなるような投稿)をカテゴリーに1:1で属するようにすれば、ご要望の内容は苦労なく実装できますが、投稿の管理が煩雑になったり、同一のドキュメントが、異なるURLで存在するなど、本末転倒な気もします。

    トピック投稿者 kujira123

    (@kujira123)

    おはようございます。
    jim912様、アドバイスありがとうございます。

    カテゴリーは複数の親カテゴリーを持つことはできないはずです

    仰るとおりです。まとめる過程で勘違いしておりました。
    実際は
    「獣>>コウモリ」と「鳥>>コウモリ」のカテゴリーそれぞれに、同じ記事群が所属する、というものでした。申し訳ありません。
    いずれにせよ正攻法では大変難しいと言うことですね・・・

    同一内容の投稿(もしくは1つの投稿のエイリアスとなるような投稿)をカテゴリーに1:1で属する
    同一のドキュメントが、異なるURLで存在

    対案として、やりたいことはまさにこの方法です!

    依頼者(身内ですが)が、どうしても「獣」から入ったときと「鳥」から入ったときの「コウモリ」の見せ方を変えたい! ということでしたので、いっそのこと記事群をごっそりと複製して、文字通り別々の記事として運用するしかないか…と思っていました。エイリアス的なもので対処できるなら、それに越したことはありません。

    お手間を取らせて申し訳ありませんが、その方法についてアドバイス頂けないでしょうか。
    宜しくお願い致します。

    トピック投稿者 kujira123

    (@kujira123)

    ※すみません、追記です。

    上記の方法について、そのエイリアスのような記事の発生は、固定ページでも実現可能なのでしょうか?(それぞれカテゴリではなく、別の親ページの子へ振り分ける)
    もともと固定ページで作成していたものを、「複数の親に所属する」という条件を満たすために、カテゴリ記事としてコンバートしたのが現状なもので…。

    モデレーター jim912

    (@jim912)

    kujira123さん、こんにちは。

    私も実装済みな訳ではないので、検証しているわけではないのですが、とりあえず概略だけ記述しておきます。

    • エイリアスの記事に、カスタムフィールドを使って元記事のIDを保存
    • the_postでフックし(フックの方法は下記)、元記事IDを示すカスタムフィールドをチェック
    • 元記事のIDが取得できたら、get_postを使って元記事のデータを取得
    • 元記事のデータが取得できたら、必要な項目(post_titleとpost_contentくらい?)を元記事のデータで上書き

    といった感じかと思います。

    the_postでのフック例

    function rewrite_alias_post( $post ) {
    	$post->post_title = 'hoge';
    }
    add_action( 'the_post', 'rewrite_alias_post' );

    ちなみにthe_postのフックは、setup_postdata関数内で行われますので、この関数を通らないデータは、そのまま出力されてしまいます。

    トピック投稿者 kujira123

    (@kujira123)

    jim912様、早速ありがとうございます!
    概略は理解できました。空ページを作成してカスタムフィールドでオリジナルページのIDを引っ張ってきて、表示の都度、オリジナルの方の内容で上書きさせる、というわけですね。

    ただ、すみません、恥ずかしながら、概略の道順はわかるのですが、それぞれ具体的にどう記述すればよいかが解りません・・・。
    固定ページ同士でエイリアスを作成するとして、page.phpへ記述すればよいのでしょうか。

    モデレーター jim912

    (@jim912)

    kujira123さん、こんにちは。

    下記のようなコードで概ねいけるはずです。テーマのfunctions.phpに追記してください。

    function rewrite_alias_post( $post ) {
    	// 元記事IDを示すカスタムフィールドをチェック
    	$master_post_id = (int)get_post_meta( $post->ID, 'mater_post', true );
    	if ( ! $master_post_id ) { return; }
    	// 元記事のIDが取得できたら、get_postを使って元記事のデータを取得
    	$master_post = get_post( $master_post_id );
    	if ( $master_post ) {
    		// 元記事のデータが取得できたら、必要な項目(post_titleとpost_contentくらい?)を元記事のデータで上書き
    		$post->post_title = $master_post->post_title;
    		$post->post_content = $master_post->post_content;
    		$post->post_excerpt = $master_post->post_excerpt;
    	}
    }
    add_action( 'the_post', 'rewrite_alias_post' );

    前述のように、上記コードはsetup_postdata関数を通るもののみに実行されますので、wp_list_pagesやwp_titleなどのタイトルは変更されませんので、ご注意ください。

    トピック投稿者 kujira123

    (@kujira123)

    jim912様、ご丁寧にありがとうございます!
    早速試しましたところ、まずタイトルは見事に上書きされました。
    …が、post_contentの部分は、残念ながら変わらずでした。

    念のため、他のwpのサイトでfunction.phpに同じコードを貼り付け、
    試したのですが、やはりタイトルのみ上書きされる状況でした。
    間違いなく元IDを引っ張ってくるところまで成功しているので、
    本文を出力する手前あたりで邪魔が入っているのかな…とも思うのですが、
    あるとすれば、どういった可能性が考えられるでしょうか。
    お手数をお掛けしてしまい申し訳ありませんが、今すこしお付き合い
    頂ければ助かります。

    モデレーター jim912

    (@jim912)

    kujira123さん、こんにちは。

    失礼しました。検証不足です。
    the_postのフックタイミングは、すでに本文の生成が一部生成され始めているので、同等の処理を行う必要がありました。

    修正してみましたので、試してみてください。

    function rewrite_alias_post( $post ) {
    	global $page, $pages, $multipage, $more, $numpages;
    
    	$master_post_id = (int)get_post_meta( $post->ID, 'mater_post', true );
    	if ( ! $master_post_id ) { return; }
    	$master_post = get_post( $master_post_id );
    	if ( $master_post ) {
    		$post->post_title = $master_post->post_title;
    		$post->post_content = $master_post->post_content;
    		$post->post_excerpt = $master_post->post_excerpt;
    
    		$numpages = 1;
    		$page = get_query_var('page');
    		if ( !$page )
    			$page = 1;
    		if ( is_single() || is_page() || is_feed() )
    			$more = 1;
    		$content = $post->post_content;
    		if ( strpos( $content, '<!--nextpage-->' ) ) {
    			if ( $page > 1 )
    				$more = 1;
    			$multipage = 1;
    			$content = str_replace("\n<!--nextpage-->\n", '<!--nextpage-->', $content);
    			$content = str_replace("\n<!--nextpage-->", '<!--nextpage-->', $content);
    			$content = str_replace("<!--nextpage-->\n", '<!--nextpage-->', $content);
    			$pages = explode('<!--nextpage-->', $content);
    			$numpages = count($pages);
    		} else {
    			$pages[0] = $post->post_content;
    			$multipage = 0;
    		}
    	}
    }
    add_action( 'the_post', 'rewrite_alias_post' );

    あと、タイトルは他にも前後記事で利用されたりしますので、上書きするよりも元記事と同じものにしておいた方が良さそうです。

    トピック投稿者 kujira123

    (@kujira123)

    jim912様、ありがとうございます!

    今度は無事、上書き表示されました!

    タイトル…確かにwp_list_pagesで作ったメニュー等だとエイリアスの方のタイトル
    が表示されますね。タイトルはキッチリ複製します。

    本当にありがとうございました!助かりました!

9件の返信を表示中 - 1 - 9件目 (全9件中)
  • トピック「複数カテゴリに所属する子カテゴリー内の記事の扱い」には新たに返信することはできません。