[WordPress]ループ内のパーマリンクやタイトルがおかしい
posted : 2018.10.08
こんにちは、ma-ya’s CREATE[まーやずくりえいと]です。
前回の記事 [WordPress]任意の投稿記事内に関連記事を表示する の実装時、関連記事を取得するループでちょっとハマりそうになったのでメモ。
関連記事を任意で抽出して表示するサンプル(実例)
先ずはサンプルから。今回の仕様は下記のような感じです。
シンプルですが今回は諸事情によりタイトルで絞り込みました。
- タイトルで絞り込み、日付順(降順)でリスト表示する
- 現在閲覧している記事にはリンクを付けない
サンプルコード(ほぼ実例)
実装時のポイント
2~6行目で絞り込み設定
基本的にはここで様々な絞り込み条件を設定します。サンプルに書いてるもの以外にもたくさんパラメータが用意されているので自由に設定するといいと思います。
他に主要なものだと↓こんなところでしょうか。
$arg = array( 'posts_per_page' => 8, //8件表示(-1で全件表示) 'category_name' => 'hogehoge', // 表示したいカテゴリーのスラッグを指定 'tag' => 'hogehoge', //表示したいタグのスラッグを指定 'post_type' => 'products', //表示したいカスタム投稿タイプ名 'post__not_in' => array($post->ID), //表示中の記事を除外 );
7行目で絞り込んだ記事データを取得し変数に格納
この時格納する変数は$my_postsなどユニークなものが望ましいです。
理由は後述。
13行目で現在開いているページのIDを取得
そして19行目でループ中の記事IDと比較して条件分岐しています。
15行目からループを回してリスト要素を書き出し
16行目のsetup_postdata( $post );と30行目のwp_reset_postdata();も忘れずに。
だいたいざっくりいうとこんな感じ。
ただし、実装前には問題がありました。
ループ内のパーマリンクやタイトルが意図しない内容を取得してしまう
具体的には以下のようなもの。
- 記事数は正常に取得できているが、タイトルが全て現在開いているページのタイトルになっている
- パーマリンクも全て現在のページのリンクになっている
これは大変。
そこで色々調べていると、WordPressテンプレートタグであるget postsでループを回す際はいくつか作法というか、注意点があることがわかりました。
- get_postsで取得した記事はユニークな変数($my_postsなど)に格納する
- ループ時の変数は $post に固定する
- ループ前に global $post; の記述をしておく
元々サンプルコードには global $post; の記述が無かったので、これを追加するだけで問題は解決。
この記述が無いと、ループ内での the_permalink(); や the_title(); がおかしくなる場合がある模様です。
どうやらsingle.phpとか、wordpressテンプレート内では③が省略可能みたいなんで、そもそもそういったバグが出るケースは少ないようですが、今回僕が最終的にやろうとしていたのは投稿記事内でショートコード経由で自作PHPファイル(関連記事用)を読み込む、というものだったので発生してしまった模様。
何となくの推測ですが、③の記述が無いことでthe_permalink(); や the_title();で取得する記事情報がメインループ(single.php)のままになってしまっていたんでしょう。
後でちゃんと調べたら、codexでもget postsループの例に③の記述がしっかりありました。
省略できるケースが多いとは言え、作法として記述はしておいた方が良いみたいです。
参考にしたサイト様やcodexページ