WordPressでイベントカレンダーを作成する

WordPressのプラグインなどを使用しないで、簡単なイベントカレンダーを作成してみます。

サンプルコード

まずはWordPressでイベントの登録画面を作成します。
今回はイベント名(タイトル)とイベント日(カスタムフィールド)のみ登録するようにします。

functions.phpに下記を追加します。

// カスタム投稿の作成
function create_posttype() {
  register_post_type('event',
    array(
      'label'         => 'イベント情報', // ラベルをまとめて指定
      'public'        => true, // 投稿タイプをパブリックにするかどうか。ユーザーが内容を投稿する場合はtrue
      'menu_position' => 5, // この投稿タイプが表示されるメニューの位置
      'hierarchical'  => false, // この投稿タイプが階層を持つかどうか
      'show_in_rest'  => false,  // Gutenbergを有効にするかどうか
      'supports' => array( // この投稿タイプがサポートする機能を指定
        'title'
      ),
      'has_archive'   => false, // アーカイブページを有効にするかどうか
      'rewrite'       => array( // この投稿タイプのパーマリンクのリライト方法を変更
        'slug' => 'event' // パーマリンク構造のスラッグを変更
      ),
      'query_var'     => false, // この投稿に使用するquery_varキーの名前を指定。falseの場合はquery_varキーを使用しない。
    )
  );
}
add_action('init', 'create_posttype');

// カスタムフィールドの追加
function add_custom_field() {
  add_meta_box('event_date', '日付', 'create_event_date', 'event', 'normal');
}
add_action('admin_menu', 'add_custom_field');

// カスタムフィールドのHTMLを追加する時の処理
function create_event_date() {
	$keyname = 'event_date';
	global $post;
	// 保存されているカスタムフィールドの値を取得
	$get_value = get_post_meta( $post->ID, $keyname, true );

	// nonceの追加
	wp_nonce_field( 'action-' . $keyname, 'nonce-' . $keyname );

	// HTMLの出力
	echo '<input name="' . $keyname . '" type="date" value="' . $get_value . '">';
}

// カスタムフィールドの保存
function save_custom_field( $post_id ) {
	$custom_fields = ['event_date'];
	foreach( $custom_fields as $d ) {
		if ( isset( $_POST['nonce-' . $d] ) && $_POST['nonce-' . $d] ) {
			if( check_admin_referer( 'action-' . $d, 'nonce-' . $d ) ) {
				if( isset( $_POST[$d] ) && $_POST[$d] ) {
					update_post_meta( $post_id, $d, $_POST[$d] );
				} else {
					delete_post_meta( $post_id, $d, get_post_meta( $post_id, $d, true ) );
				}
			}
		}
	}
}
add_action('save_post', 'save_custom_field');

eventというカスタム投稿を作成して、そのカスタム投稿にevent_dateという名前で日付を登録するカスタムフィールド を追加しました。
カスタム投稿カスタムフィールドは過去に記事を投稿していますので、詳しくはそちらを確認ください。
これで以下のような登録画面が作成できました。

次にイベントカレンダーをショートコードで表示できるようにしてみます。
functions.phpに下記を追加します。

// イベントカレンダー追加のショートコード
function event_calendar($atts) {
	$query = new WP_Query(array(
		'post_type'      => 'event',
		'posts_per_page' => 10,
	));
	$eventData = array();
	if($query->have_posts()):
		while($query->have_posts()): $query->the_post();
			$jsonItem = array(
				'id'          => get_the_id(),
				'title'       => get_the_title(),
				'date'        => get_post_meta(get_the_id(), event_date, true),
			);
			array_push($eventData, $jsonItem);
		endwhile; wp_reset_postdata();
	endif;
	return '<script>const eventData = ' . json_encode($eventData, JSON_UNESCAPED_UNICODE) . '</script><div class="js-event-calendar"></div><script src="/assets/js/calendar.js"></script>';
}
add_shortcode('event', 'event_calendar');

登録したイベント情報をeventDataという名前でJavaScriptの変数に格納して、.js-event-calendarというクラス名でイベントカレンダーの出力エリアを用意するようにしています。
ショートコードの作成に関しては以前に記事を投稿しています。

これで[event]というショートコードを使うと、イベントカレンダー生成に必要なデータが出力されるようになりました。

最後に、出力したデータを使用してJavaScriptでカレンダーを生成します。
/assets/js/calendar.js を使用する想定にしていますが、ファイル名やパスを変更したい場合は上記functions.php内の出力パスを変更ください。

window.onload = function() {
  // 現在の年月の取得
  var current = new Date();
  var year = current.getFullYear();
  var month = current.getMonth() + 1;

  // カレンダーの表示
  var wrapper = document.querySelector('.js-event-calendar');
  add_calendar(wrapper, year, month);
}

/**
 * 指定した年月のカレンダーを表示する
 * @param {object} wrapper - カレンダーを追加する親要素
 * @param {number} year    - 年の指定
 * @param {number} month   - 月の指定
 */
function add_calendar(wrapper, year, month) {
  // 現在カレンダーが追加されている場合は一旦削除する
  wrapper.textContent = null;

  // カレンダーに表示する内容を取得
  var headData = generate_calendar_header(wrapper, year, month);
  var bodyData = generate_month_calendar(year, month, eventData);

  // カレンダーの要素を追加
  wrapper.appendChild(headData);
  wrapper.appendChild(bodyData);
}

/**
 * 指定した年月のカレンダーのヘッダー要素を生成して返す
 * @param {object} wrapper - カレンダーを追加する親要素
 * @param {number} year    - 年の指定
 * @param {number} month   - 月の指定
 */
function generate_calendar_header(wrapper, year, month) {
  // 前月と翌月を取得
  var nextMonth = new Date(year, (month - 1));
  nextMonth.setMonth(nextMonth.getMonth() + 1);
  var prevMonth = new Date(year, (month - 1));
  prevMonth.setMonth(prevMonth.getMonth() - 1);

  // ヘッダー要素
  var cHeader = document.createElement('div');
  cHeader.className = 'calendar-header';

  // 見出しの追加
  var cTitle = document.createElement('div');
  cTitle.className = 'calendar-header__title';
  var cTitleText = document.createTextNode(year + '年' + month + '月');
  cTitle.appendChild(cTitleText);
  cHeader.appendChild(cTitle);

  // 前月ボタンの追加
  var cPrev = document.createElement('button');
  cPrev.className = 'calendar-header__prev';
  var cPrevText = document.createTextNode('prev');
  cPrev.appendChild(cPrevText);
  // 前月ボタンをクリックした時のイベント設定
  cPrev.addEventListener('click', function() {
    add_calendar(wrapper, prevMonth.getFullYear(), (prevMonth.getMonth() + 1));
  }, false);
  cHeader.appendChild(cPrev);

  // 翌月ボタンの追加
  var cNext = document.createElement('button');
  cNext.className = 'calendar-header__next';
  var cNextText = document.createTextNode('next');
  cNext.appendChild(cNextText);
  // 翌月ボタンをクリックした時のイベント設定
  cNext.addEventListener('click', function() {
    add_calendar(wrapper, nextMonth.getFullYear(), (nextMonth.getMonth() + 1));
  }, false);
  cHeader.appendChild(cNext);

  return cHeader;
}

/**
 * 指定した年月のカレンダー要素を生成して返す
 * @param {number} year     - 年の指定
 * @param {number} month    - 月の指定
 * @param {object} eventData - イベントの情報
 */
function generate_month_calendar(year, month, eventData) {
  var weekdayData = ['日', '月', '火', '水', '木', '金', '土'];
  // カレンダーの情報を取得
  var calendarData = get_month_calendar(year, month);

  var i = calendarData[0]['weekday']; // 初日の曜日を取得
  // カレンダー上の初日より前を埋める
  while(i > 0) {
    i--;
    calendarData.unshift({
      day: '',
      weekday: i
    });
  }
  var i = calendarData[calendarData.length - 1]['weekday']; // 末日の曜日を取得
  // カレンダー上の末日より後を埋める
  while(i < 6) {
    i++;
    calendarData.push({
      day: '',
      weekday: i
    });
  }

  // カレンダーの要素を生成
  var cTable = document.createElement('table');
  cTable.className = 'calendar-table';

  var insertData = '';
  // 曜日部分の生成
  insertData += '<thead>';
  insertData += '<tr>';
  for (var i = 0; i < weekdayData.length; i++) {
    insertData += '<th>';
    insertData += weekdayData[i];
    insertData += '</th>';
  }
  insertData += '</tr>';
  insertData += '</thead>';

  // 日付部分の生成
  insertData += '<tbody>';
  for (var i = 0; i < calendarData.length; i++) {
    if(calendarData[i]['weekday'] <= 0) {
      insertData += '<tr>';
    }
    insertData += '<td>';
      var ymd = year + '-' + month + '-' + calendarData[i]['day'];
      for (var j = 0; j < eventData.length; j++) {
        if(dateFormat(eventData[j]['date']) === ymd) {
          insertData += '<div>' + calendarData[i]['day'] + '</div>';
          insertData += '<div>' + eventData[j]['title']  + '</div>';
          break;
        }
        if(j >= eventData.length - 1) {
          insertData += calendarData[i]['day'];
        }
      }
    insertData += '</td>';
    if(calendarData[i]['weekday'] >= 6) {
      insertData += '</tr>';
    }
  }
  insertData += '</tbody>';

  cTable.innerHTML = insertData;
  return cTable;
}

/**
 * 指定した年月のカレンダー情報を返す
 * @param {number} year  - 年の指定
 * @param {number} month - 月の指定
 */
function get_month_calendar(year, month) {
  var firstDate = new Date(year, (month - 1), 1); // 指定した年月の初日の情報
  var lastDay = new Date(year, (firstDate.getMonth() + 1), 0).getDate(); // 指定した年月の末日
  var weekday = firstDate.getDay(); // 指定した年月の初日の曜日

  var calendarData = []; // カレンダーの情報を格納
  var weekdayCount = weekday; // 曜日のカウント用
  for (var i = 0; i < lastDay; i++) {
    calendarData[i] = {
      day: i + 1,
      weekday: weekdayCount
    }
    // 曜日のカウントが6(土曜日)まできたら0(日曜日)に戻す
    if(weekdayCount >= 6) {
      weekdayCount = 0;
    } else {
      weekdayCount++;
    }
  }
  return calendarData;
}

/**
 * 日付の形式整形
 * @param {number} date - 整形する日付
 */
function dateFormat(date) {
  // 日付の変換
  var dateStr = new Date(date);
  // 年の取得
  var year = dateStr.getFullYear();
  // 月の取得
  var month = dateStr.getMonth() + 1;
  // 日の取得
  var day = dateStr.getDate();
  return year + '-' + month + '-' + day;
}

以前投稿したリンク付きのカレンダーを作成するのコードをペースにしています。
カレンダーにイベント名を表示するという簡単な機能のみですが、WordPressでイベントカレンダーを作成できました。

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2021年11月
 123456
78910111213
14151617181920
21222324252627
282930