wordpress

表示中のカテゴリーに属する記事IDを配列で取得できる『get_objects_in_term』はステータスが公開以外の記事も取得してしまうよ

こんにちは!みぞれ(@xxmiz0rexx)です。
すごいニッチかもしれないんだけど、WordPressでカテゴリ一覧を表示している時に、さらに記事を絞り込むためにタグ一覧を表示することってありますよね?

そんな時はWordPress Codexにも載っている以下の方法を参考にする人が多いと思うんですが、実はこれだと下書きなどに設定しているタグも出力されてしまいます。

PHP
<?php
if ( is_category() ) {
    // 現在のカテゴリーのIDを取得
    $cat_id = get_query_var( 'cat' );
    // 表示中のカテゴリーに属する投稿のIDを配列で取得
    $current_posts = get_objects_in_term( $cat_id, 'category' );
    // 表示中のカテゴリーに属する投稿に付けられたタグの情報をまとめて取得
    $current_tags = wp_get_object_terms( $current_posts, 'post_tag' );
    if ( $current_tags ) {
        echo 'このカテゴリーの投稿に付いているタグの一覧:<ul>' . "\n";
        foreach ( $current_tags as $tag )
            echo '<li>' . $tag->name . '</li>' . "\n";
        echo '</ul>';
    }
}
?>

それだとちょっと困ってしまったので対処法を考えました。

問題点

先ほどのCodexにあったコードだと、下書きなどの記事も対象に含まれてしまい、公開中の記事には設定していないタグも一覧として出力されてしまうのです。こんな感じ。

どうしてそんな挙動なのか謎すぎる上に、せめて公開中の記事だけを絞り込めるパラメーターなどがあれば良いんですが、それもないので個人的には大問題でした。うっかりリンク踏むとWordPressが「重大なエラー」とか言ってくるし。。

ゴール

表示中のカテゴリに属する”公開中”の記事IDを取得し、その記事たちに設定されているタグの一覧を出力する

ついでに取得したタグは[ドメイン+カテゴリ名?tag=XXXX]という形式のリンクにします。というわけで以下のような書き方にしてみました。

PHP
<?php
if (is_category()) {

  // 現在のカテゴリーのIDを取得
  $cat_id = get_query_var('cat');
  if (!$cat_id) {
    $cat_now = get_the_category();
    $cat_now = $cat_now[0];
    $cat_id  = $cat_now->cat_ID;
  }

  // 表示中のカテゴリーに属する投稿のIDを配列で取得
  $current_posts = get_objects_in_term($cat_id, 'category');
  //配列に入れた記事IDの中から公開中のものだけを新たな配列に格納
  foreach ($current_posts as $post) {
    if (get_post_status($post) == 'publish') {
      $publish_posts[] = $post;
    }
  }
}
//公開中の投稿に付けられたタグの情報をまとめて取得
$current_tags = wp_get_object_terms($publish_posts, 'post_tag', array('exclude' => '12', 'orderby' => 'count', 'order' => 'DESC'));

if (is_category() and $current_tags) {
  echo '<ul class="tagList">' . "\n";
  $tag_count = 0;
  foreach ($current_tags as $tag) {
    if ($tag_count < 10) {
      echo '<li><a href="/' . get_category($cat)->slug . '?tag=' . $tag->slug . '">' . $tag->name . '</a></li>' . "\n";
      $tag_count++;
    }
  }
  echo '</ul>';
}
?>

取得した$current_postsをforeachで回して、ステータスが「公開中」のものだけを$publish_postsという変数の中に再格納してwp_get_object_termsに渡しています。

無事、公開中の記事から取得されたタグだけになりました。

さいごに

というわけで、『表示中のカテゴリーに属する記事IDを配列で取得できる『get_objects_in_term』はステータスが公開以外の記事も取得してしまうよ』でした!走り書きになってしまったけど、誰か同じように困ってる人に届いてくれると嬉しいです。

以上、みぞれ(@xxmiz0rexx)でした!!