macoblog

「ゲーム × プログラミング」で生きていく

MMORPGに人生捧げてみ?

【WordPress】任意のカテゴリ順で記事を表示する方法

PHP WordPress プログラミング

このカテゴリを含む記事を全て表示した後、別のカテゴリに関する記事を表示する。

「カテゴリ毎にソートした上で表示したい」こんなニーズに答える記事になります。

実際のコードも公開していますのでwordpress学習の参考にどうぞ。

カテゴリ順?つまりどういうこと?

カテゴリ1,カテゴリ2,カテゴリ3という3つのカテゴリがあったとして、下記のようなことをしたい。

最初にカテゴリ3の記事を全て表示して、次にカテゴリ1の記事を全て表示、最後にカテゴリ3の記事を全て表示する

こういうことです。

素直に考えれば方法は3つ

  • カテゴリを指定してそれぞれループさせる
  • ソート用のカスタムフィールドを作る
  • オプションで何か指定する

それぞれ簡単に解説します。

カテゴリを指定してそれぞれループさせる

つまり、カテゴリを指定したループ処理を3つ用意するってことです。

カテゴリが増えた時どうすんのって話になりかねないのでボツ、ってかキレイじゃないからヤダ。

ソート用のカスタムフィールドを作る

ソートのためだけにカスタムフィールドを作るってのもなんかヤダ、ボツ。

オプションで何か指定する

WP_Queryを使ったループだといろいろオプションを付けれて便利なんですが、「これだ!」ってものがなかった。

探し切れてないだけかもしれない、時間かけるのもあれなので自力でソートしてみました。

スポンサードサーチ


自力で任意のカテゴリ順にソートする方法

自力で任意のカテゴリ順にソートする方法

カテゴリ1(cat1)→カテゴリ2(cat2)→カテゴリ3(cat3)の順で表示させてみます。

先に完成コードを紹介

誰でもわかりやすいよう冗長な記述となっています、ご容赦ください。

$args = array(
  'post_type' => 'post',
  'posts_per_page' => -1,
);
$my_query = new WP_Query( $args );

if ($my_query->have_posts()):
  // 記事を格納する配列を用意
  $sort_posts = [];

  // ループ開始
  while ( $my_query->have_posts() ) : $my_query->the_post();
    // カテゴリを取得
    $faqcat = get_the_category();
    // 本文を取得
    $content = apply_filters('the_content',get_the_content());
    // 優先度を格納
    $priority = 0;
    // カテゴリスラッグによって優先度を振り分け
    switch ($faqcat[0]->slug) {
      case 'cat2':
        $priority = 1;
        break;
      case 'cat3':
        $priority = 2;
        break;
    }

    // 用意した配列に必要なデータだけ入れ直す
    $sort_posts[] = array(
                      'priority'   => $priority,
                      'catname' => $faqcat[0]->name,
                      'title'   => get_the_title(),
                      'content' => $content
                    );
                    
  endwhile;
  // ループ終了

  // ソート用の配列を用意
  foreach ($sort_posts as $key => $value) {
    $sort[$key] = $value['priority'];
  }

  // ソート用の配列と対象の配列を使って昇順並び替え
  array_multisort($sort, SORT_ASC, $sort_posts);

  // 記事を出力する
  foreach ($sort_posts as $key => $value) {
    echo $value['catname'];
    echo $value['title'];
    echo $value['content'];
  }
endif;

wp_reset_postdata();

簡単に解説します。

まず何を使ってソートするかを決める

今回はそれぞれのカテゴリに優先度という値を持たしてみました。

17~35行目(抜粋)

// 優先度を格納
$priority = 0;
// カテゴリスラッグによって優先度を振り分け
switch ($faqcat[0]->slug) {
 case 'cat2':
   $priority = 1;
   break;
 case 'cat3':
   $priority = 2;
   break;
}

// 用意した配列に必要なデータだけ入れ直す
$sort_posts[] = array(
                 'priority'   => $priority,
                 'catname' => $faqcat[0]->name,
                 'title'   => get_the_title(),
                 'content' => $content
               );

スラッグを使ってswitchで優先度を振り分けています、そしてその値を配列に追加しています。

優先度を持たせずスラッグを使ってそのままソートすることも出来ましたが、自由度が低いのでやめました。

スラッグにプレフィックスを付ける(例:「a-cat1」「b-cat1」「c-cat1」)という手もありますが、ちょっとね・・・。

array_multisort関数でソートする

array_multisort関数を使った多次元配列の並び替えに関しては下記を参考にどうぞ。

【PHP基礎】多次元配列を任意の値で並び替える方法【初心者向け】

ソート用の配列を用意(今回は優先度を格納)します。

40~43行目(抜粋)

// ソート用の配列を用意
foreach ($sort_posts as $key => $value) {
  $sort[$key] = $value['priority'];
}

array_multisort関数を使って並び替えを実行。

45~46行目(抜粋)

// ソート用の配列と対象の配列を使って昇順並び替え
array_multisort($sort, SORT_ASC, $sort_posts);

最後にソートした配列を出力するだけですね。

48~53行目(抜粋)

// 記事を出力する
foreach ($sort_posts as $key => $value) {
  echo $value['catname'];
  echo $value['title'];
  echo $value['content'];
}

以上になります。

終わりに

優先度の振り分けを変えるだけで好きなように順番を決めることが可能です。

ただ、スラッグ名を変えるとこっちも変えないといけないってのが難点です。

もう一つ、管理画面から順番を決めれないってのもモヤモヤしますね。

改良の余地ありです、とはいえ実際に使えるコードではありますので参考程度にどうぞ。

以上になります。

Twitterでも情報や経過を発信していますのでフォローよろしくお願いします。

不明点やアドバイスなどありましたら、コメントかTwitterからお願いします。