1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

WordPressで月別予定一覧を作ったので記録

Last updated at Posted at 2020-01-10

月ごとのイベント開催カレンダーとかにありがちなやつを作りました。

仕様

ワイヤーフレーム

image.png

投稿一覧

  • [月別インデックス]をクリックするとその月が[日程]に含まれる投稿がタブ切り替え方式で表示される
  • [日程]は、[開始日][終了日]で設定されている。[開始日]のみの投稿もある。
  • 今日以降の[日程]が含まれた投稿が表示される
  • 投稿はカスタム投稿タイプで作成する

実装

カスタム投稿タイプ

一般的な方法で作成済みとします。説明は割愛。
スラッグは、"events"にしました。

カスタムフィールドを作成

  • 開始日
  • [フィールドタイプ]…[デイトピッカー]
  • [返り値のフォーマット]…[Custom] → "Y-m-d"
  • 終了日
  • 開始日と同じ
  • 但し[必須か?]は[いいえ]にする(開始日のみの投稿もあるので)

image.png

テンプレートファイル

archive.php
<?php
$today = date('Y-m-d');
// $today = date("Y-m-d", strtotime('2020-01-31')); //for debug
$args = array(
  'post_type'=> 'events',
  'orderby'  => 'meta_value',
  'order'    => 'ASC', //昇順
  'meta_key' => 'evstartdate', //ACFのフィールド名
  'meta_query' => array( // 判定条件…(開始日 >= 今日)or(終了日 >= 今日)
    'relation' => 'OR',
    array(
      'key'     => 'evstartdate',
      'value'   => $today,
      'type'    => 'date',
      'compare' => '>=',
    ),
    array(
      'key' => 'evenddate',
      'value' => $today,
      'type'    => 'date',
      'compare' => '>=',
    ),
  ),
  'posts_per_page' => 0,
);
$query = new WP_Query( $args );
if( $query->have_posts() ) :
  /*================================
  月別投稿リスト取得
  =================================*/
  while ( $query->have_posts() ) : $query->the_post();
    $date1 = date('Y-m-d',strtotime(get_field('evstartdate', false, false)));
    if ( get_field('evenddate') ) {
      // 終了日が設定されている場合
      $date2ym = date('Y-m',strtotime(get_field('evenddate', false, false)));

      // 開始日が今日より前・・今日の月~終了月を設定
      // 開始日が今日以降・・・開始日月~終了月を設定
      $tmpdate = ( $today > $date1 ) ? $today : $date1;

      while( $date2ym >= date("Y-m", strtotime($tmpdate)) ) {
        $eventlist[ date("Y-m", strtotime($tmpdate)) ][] = get_the_ID();
        $tmpdate = date("Y-m-1", strtotime($tmpdate));//月はじめに変換(31日等の場合に月を飛び越える事を防ぐため)
        $tmpdate = date("Y-m-d",strtotime($tmpdate . "+1 month"));//1ヶ月後の月を取得
      }
    } else {
      // 終了日が未設定の場合は、開始日の月のみ設定
      $eventlist[ date("Y-m", strtotime($date1)) ][] = get_the_ID();
    }
  endwhile;
// echo '<pre>';var_dump($eventlist); echo '</pre>';

  if( isset($eventlist) ) :
    /*================================
    月インデックス出力
    =================================*/
?>
    <div class="month-index">
      <ul>
<?php
    foreach( $eventlist as $ym => $archive ) :
      $ym_arr = explode( '-', $ym );
      echo '<li>' . $ym_arr[0].'年'.$ym_arr[1].'月</li>'; // 月インデックス出力
    endforeach;
?>
<?php wp_reset_postdata(); //必須 ?>
        </div>
        <div class="month-content">
          <div class="active">
<?php
    /*================================
    月別投稿リスト出力
    =================================*/
    foreach ($eventlist as $value) :
      $args = array(
        'post_type' => 'events',
        'post__in' => $value,
        'posts_per_page' => 0,
      );
      $query = new WP_Query( $args );
?>
            <ul class="ls-reports">
  <?php while ( $query->have_posts() ) : $query->the_post(); ?>
<?php
    /*================================
    投稿の内容を出力します!
    =================================*/
?>
  <?php endwhile; ?>
            </ul>
          </div>
          <div>
<?php
      wp_reset_postdata(); //必須
    endforeach;
?>
          </div>
        </div>
  <?php else : ?>
        <p style="text-align:center">実施予定は調整中です。</p>
  <?php endif; ?>
<?php else : ?>
        <p style="text-align:center">現在、開催予定のイベントはありません。</p>
<?php endif; ?>

タブ切り替え処理

js
jQuery(function($){
  // 月別投稿 タブ切り替え
  var $index = $('.month-index li');
  var $content = $('.month-content > div');
  $index.eq(0).addClass('active');
  $content.eq(0).addClass('active');

  $index.click(function(){
    $index.removeClass('active');
    $(this).addClass('active');
    $content.removeClass('active');
    $content.eq($(this).index()).addClass('active');
  });
});

SASS

※タブ切り替えに関わる部分のみ


.month-index {
  ul {
    display: flex;
    flex-wrap: wrap;
    li {
      flex: 0 1 29%;
    }
  }
}
.month-content {
  > div {
    display: none;
    &.active {
      display: block;
    }
  }
}

説明

タブ切り替えを踏まえ、以下のようなhtmlを作ることにする。


<div class="month-index">
  <ul>
    <li>2020年1月</li>
    <li>2020年2月</li>
  </ul>
</div>
<div class="month-content">
  <!-- 2020年1月の投稿 -->
  <div>
    <ul>
      <li>投稿が入ります</li>
      <li>投稿が入ります</li>
    </ul>
  </div>
  <!-- 2020年2月の投稿 -->
  <div>
    <ul>
      <li>投稿が入ります</li>
      <li>投稿が入ります</li>
    </ul>
  </div>
</div>

php では、$eventlistがポイント。


$today = date('Y-m-d');
// $today = date("Y-m-d", strtotime('2020-01-31')); //for debug
$args = array(
  'post_type'=> 'events',
  'orderby'  => 'meta_value',
  'order'    => 'ASC', //昇順
  'meta_key' => 'evstartdate', //ACFのフィールド名
  'meta_query' => array( // 判定条件…(開始日 >= 今日)or(終了日 >= 今日)
    'relation' => 'OR',
    array(
      'key'     => 'evstartdate',
      'value'   => $today,
      'type'    => 'date',
      'compare' => '>=',
    ),
    array(
      'key' => 'evenddate',
      'value' => $today,
      'type'    => 'date',
      'compare' => '>=',
    ),
  ),
  'posts_per_page' => 0,
);
$query = new WP_Query( $args );
if( $query->have_posts() ) :
  /*================================
  月別投稿リスト取得
  =================================*/
  while ( $query->have_posts() ) : $query->the_post();
    $date1 = date('Y-m-d',strtotime(get_field('evstartdate', false, false)));
    if ( get_field('evenddate') ) {
      // 終了日が設定されている場合
      $date2ym = date('Y-m',strtotime(get_field('evenddate', false, false)));

      // 開始日が今日より前・・今日の月~終了月を設定
      // 開始日が今日以降・・・開始日月~終了月を設定
      $tmpdate = ( $today > $date1 ) ? $today : $date1;

      while( $date2ym >= date("Y-m", strtotime($tmpdate)) ) {
        $eventlist[ date("Y-m", strtotime($tmpdate)) ][] = get_the_ID();
        $tmpdate = date("Y-m-1", strtotime($tmpdate));//月はじめに変換(31日等の場合に月を飛び越える事を防ぐため)
        $tmpdate = date("Y-m-d",strtotime($tmpdate . "+1 month"));//1ヶ月後の月を取得
      }
    } else {
      // 終了日が未設定の場合は、開始日の月のみ設定
      $eventlist[ date("Y-m", strtotime($date1)) ][] = get_the_ID();
    }
  endwhile;

上記で以下のような配列を作成し、それをもとに月別インデックスと、月別の投稿一覧を生成する。

array(5) {
  ["2019-05"]=>
  array(1) {
    [0]=>
    int(2303)
  }
  ["2019-06"]=>
  array(1) {
    [0]=>
    int(2303)
  }
  ["2019-09"]=>
  array(2) {
    [0]=>
    int(2302)
    [1]=>
    int(2301)
  }
  ["2019-12"]=>
  array(3) {
    [0]=>
    int(2318)
    [1]=>
    int(2328)
    [2]=>
    int(2329)
  }
  ["2020-03"]=>
  array(1) {
    [0]=>
    int(2339)
  }
}

おわり
もっとスマートな方法があれば教えて下さい。

参考サイト

【WordPress】wp_get_archivesを使わずに特定カテゴリーの年月アーカイブリストを表示したい
https://www.rcnt.jp/blog/wordpress-wp_get_archives/

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?