- web design -

blog

[WordPress]ループ内のパーマリンクやタイトルがおかしい

WordPress

こんにちは、ma-ya’s CREATE[まーやずくりえいと]です。

 

前回の記事 [WordPress]任意の投稿記事内に関連記事を表示する の実装時、関連記事を取得するループでちょっとハマりそうになったのでメモ。

 

関連記事を任意で抽出して表示するサンプル(実例)

先ずはサンプルから。今回の仕様は下記のような感じです。

シンプルですが今回は諸事情によりタイトルで絞り込みました。

  1. タイトルで絞り込み、日付順(降順)でリスト表示する
  2. 現在閲覧している記事にはリンクを付けない

サンプルコード(ほぼ実例)

 

実装時のポイント

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でループを回す際はいくつか作法というか、注意点があることがわかりました。

  1. get_postsで取得した記事はユニークな変数($my_postsなど)に格納する
  2. ループ時の変数は $post に固定する
  3. ループ前に global $post; の記述をしておく

元々サンプルコードには global $post; の記述が無かったので、これを追加するだけで問題は解決。

この記述が無いと、ループ内での the_permalink(); や the_title(); がおかしくなる場合がある模様です。

 

どうやらsingle.phpとか、wordpressテンプレート内では③が省略可能みたいなんで、そもそもそういったバグが出るケースは少ないようですが、今回僕が最終的にやろうとしていたのは投稿記事内でショートコード経由で自作PHPファイル(関連記事用)を読み込む、というものだったので発生してしまった模様。

 

何となくの推測ですが、③の記述が無いことでthe_permalink(); や the_title();で取得する記事情報がメインループ(single.php)のままになってしまっていたんでしょう。

 

後でちゃんと調べたら、codexでもget postsループの例に③の記述がしっかりありました。

省略できるケースが多いとは言え、作法として記述はしておいた方が良いみたいです。

 

参考にしたサイト様やcodexページ