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でイベントカレンダーを作成できました。
コメントが承認されるまで時間がかかります。