カスタムフィールドの日付から月別に分類して表示する。WordPress

はじめに(やりたいこと)

「イベント情報」のようなカスタム投稿があります。

その「イベント情報」には、イベントの開催日程というカスタムフィールドがある。

開催日程の月ごとに分別して、表示させたい。

ここで注意したいのは、投稿日ではないということ。

投稿された日毎に分類するなら、方法が他にある。

カスタムフィールド の値を受け取って、それに基づいて分類する必要がある。

表示のイメージとしては、以下の通り。

  • 2020年9月開催予定
    • イベントA
    • イベントB
    • イベントD
    • イベントF
  • 2020年10月開催予定
    • イベントC
    • イベントE

その他の条件

カスタムフィールド はカレンダー型で選択するようになっている。

「イベント情報」の他に、「開催時間帯」「会場」「住所」「人数」のフィールドが存在する。

どんな感じで実装するのか(まずは言葉で)

サブループ を使って「イベント情報」の投稿情報を取得する。

各投稿の情報をひとまとめにする。

[「開催日程」、「開催時間帯」、「会場」、「住所」、「人数」]

こんなイメージ。↑

それぞれの「イベントの開催日程」というフィールドの値を元に分類する。

[2020年9月、2020年10月、・・・]

この配列に、先ほど作成した各投稿毎の配列を入れていく。

入れるときは、開催日程のフィールドに基づく分類をする。

そうすると、

  • 2020年9月
    • イベントA
    • イベントB
    • イベントD
    • イベントF
  • 2020年10月
    • イベントC
    • イベントE

のような二次元連想配列が出来上がる。

あとは、foreachでループさせる。

2020年9月のなかでforeach、それが終わったら2020年10月でforeachと言った具合に。

それでは、実際にコードをみていく。

<?php // 投稿のカスタムフィールド値を元に年別リストを表示する方法
$args = array( // クエリの作成
  'post_type' => 'イベント情報', // 投稿タイプの指定
  'orderby' => 'date', // 日付順で表示
  'posts_per_page' => -1 // すべての投稿を表示
);
$event_query = new WP_Query($args); 
if($event_query->have_posts()){ // 投稿があれば表示
  $month_array = [];
  while ($event_query->have_posts()): $event_query->the_post(); // ループの開始
    //記事データ配列の作成
    $post_data["event_date"] = get_field('event_date'); 
    $post_data["event_date_time"] = get_field('event_date_time'); 
    $post_data["event_place"] = get_field('event_place'); 
    $post_data["event_address"] = get_field('event_address'); 
    $post_data["event_capacity"] = get_field('event_capacity'); 
    //記事に設定された日付データを取得
    $newsDate = get_field("event_date");
    //「/」で文字列「YYYY/MM/DD」を分割
    $date_explode = explode("/",$newsDate);//[0]=>YYYY [1]=>MM [2]=>DD
    //配列のキー名を「YYYY年MM月」にする→今後、同じ年月の物はこのキーの配下にデータが入る
    $month_array[$date_explode[0]."年".$date_explode[1]."月"][] = $post_data; //キー名:”YYYY年MM月”
  endwhile;
}
foreach ($month_array as $key => $value) {
  // $keyには「”YYYY年MM月”」が入る→タイトルとする
  ?>
  <div class="month-category-title">
    <p><?php echo $key ?></p>
  </div>
  <?php
  foreach ($value as $key1 => $val) {
    // $keyには連番の番号が入る→使用しない
    //このループ内に記事のレイアウトを記載する
    ?>
  <div class="month-category-each">
    <p><?php 
      $title = new DateTime($val['event_date']); $title = $title->format('n月j日'); echo $title;
      $week = array('日', '月', '火', '水', '木', '金', '土');
      $w = new DateTime($val['event_date']);
      $w = $w->format('w'); echo '('.$week[$w].')';
      ?>
    </p>
    <p><?php echo $val['event_date_time']; ?></p>
    <p><?php echo $val['event_place']; ?></p>
    <p><?php echo $val['event_address']; ?></p>
    <p><?php echo $val['event_capacity']; ?></p>
  </div>
  <?php } ?>
<?php } ?>

説明のため、HTML部分は簡略的に、pダグで囲っただけである。

コードの解説

〜9行目 wordpressおなじみのサブループ で投稿を取得している。

10行目〜 get_field関数でそれぞれのカスタムフィールド の入力値を配列で。

ここで豆ポイント。

配列にただ入れるのではなく、連想配列にする!のがポイント。

連想配列とは、それぞれの値に名前がある配列のこと。

代入するときに、以下の記述をすることで名前を付けられる。

$post_data["event_date"] = get_field('event_date'); 

これは、get_field関数でevent_dateフィールドの値を$post_data配列に代入する記述。

$post_dataの後に[]があるのに注意!

ここに書いた物は、代入しようとしているものの「名前」になる。

phpでは、この「名前」のことを「キー」と読んだりする。phpだけじゃなく、プログラム一般で使われる言葉なので理解しておいて損はない。

つまり、event_dateという名前で、値を格納している。

$post_dataが[「開催日程」、「開催時間帯」、「会場」、「住所」、「人数」]である。

22行目〜 $post_dataを、$month_arrayの中の、名前を付けた配列に追加する。

少難しかったかもしれない。

階層構造は以下の通り。

$month_array > $post_data > いろいろ。

ただし、先ほどとは少し違うことに触れておく。

$month_array[お名前][] = $post_dataとなっている。

[]が一個多いのは、お名前を付けた配列に$post_dataを追加していくからである。

つまり、[$post_data, $post_data, $post_data, ….]と$post_dataを追加していくのだ。

何度もいうが、この配列には、お名前がついていて、それが、[$date_explode[0].”年”.$date_explode[1].”月”]
これだ。

「2020年○月」のようなフォーマットにしたかったので、少しいじっている。適宜調べて欲しい。

ここまでの処理で出来上がるのは、こんな連想配列だ。

$month_array["2020年08月"] => array(
  [0] => array(
    ["event_date"] => "hoge",
    ["event_date_time"] => "hoge",
    ["event_place"] => "hoge",
    ["event_address"] => "hoge",
    ["event_capacity"] => "hoge",
  );
  [1] => array(
    ["event_date"] => "hoge",
    ["event_date_time"] => "hoge",
    ["event_place"] => "hoge",
    ["event_address"] => "hoge",
    ["event_capacity"] => "hoge",
  );
  [2] => array(
    ["event_date"] => "hoge",
    ["event_date_time"] => "hoge",
    ["event_place"] => "hoge",
    ["event_address"] => "hoge",
    ["event_capacity"] => "hoge",
  );
  [3] => array(
    ["event_date"] => "hoge",
    ["event_date_time"] => "hoge",
    ["event_place"] => "hoge",
    ["event_address"] => "hoge",
    ["event_capacity"] => "hoge",
  );
);

$month_array["2020年09月"] => array(
  [0] => array(
    ["event_date"] => "hoge",
    ["event_date_time"] => "hoge",
    ["event_place"] => "hoge",
    ["event_address"] => "hoge",
    ["event_capacity"] => "hoge",
  );
  [1] => array(
    ["event_date"] => "hoge",
    ["event_date_time"] => "hoge",
    ["event_place"] => "hoge",
    ["event_address"] => "hoge",
    ["event_capacity"] => "hoge",
  );
);

お名前が一緒の時は、一緒のお名前の配列に追加されていく。
お名前が違う時は、違う時のお名前がついた配列が新しく作成されて、その中に$post_dataが追加されていく。

25行目〜あとは、foreachを二層にしてやれば良い。

foreachの中で好きなようにhtmlを書いて、整えれば出来上がりだ。

総括

配列。

は、すんなり理解できると思う。

だが連想配列はどうだろうか。

少しphp初心者にはとっつきにくいのでは?

自身も最初は配列でforeachを回そうとしたが、それではこの機能を実装するのに可変変数たるものを利用してしまうのかもしれなかったり、、、結局配列だけで完成させることは諦めてしまった。

だが、連想配列にすると、簡潔にいくとわかった。

配列と、連想配列。なぜ二種類の配列が存在するのか、ようやくわかった気がする。

wordpressのお仕事をするにあたって、こういうシステムチックなことをやってる時が楽しい。コーダーとして働いているが、プログラマになるべきだな。

コメント

タイトルとURLをコピーしました