Fullcalendarを苦難の末に導入した。

https://mondaymarket.biz (すでに閉鎖。例としては https://shimayu.co.jp/classroom をご覧ください)で営業日カレンダーを表示することになり、その仕様を考えた時、プラグインのカレンダーでは機能が多すぎたり、なかったり、いろいろ手の届かないことがあり、調べているうちに Fullcalendar にたどり着きました。

仕様では

  1. グーグルカレンダーと連携
  2. 営業開始時間がわかれば良い
  3. あまり凝ったレイアウト(特にいろいろなボタン類)は勘弁してもらいたい

というもの。
当初はプラグインの「MyCalendar」でいいかと思ったけど、グーグルカレンダーを引き込むのがよくわからず…んで、最初は直接グーグルカレンダーを埋め込んで表示していたのです。
そうすると③が引っかかってくるわけです。
まあその前にちょっとCSSで色変えようかなと思ったら効かない。←そらそーだ。
んで調べてみたら「Fullcalendarならいろいろレイアウトもできまっせ」という記事を発見!
じゃあそれに変えればいいじゃーんと、かなり楽観的に導入したのです。

…タイトルに「苦難の末」とあるのは、この後判明します。

FullcalendarはJavascriptのセットで、プラグインのようにちょいちょいっとインストールできるものではありません。
一応知ってました(・∀・)クサッテモプログラマーダモノ
で、本家に行ってDLしてきて、ZIPを解凍すると…

…ん?
……なんかファイルちがくね?

そう。この時の最新バージョンは5.5.1です。
でもこの時点でネット上に解説が載っているのはV4シリーズがほとんど。というか、それ以前V1シリーズのものとか現役っぽく載ってるくらい。
Fullcalendarの開発が活発で、どんどんリリースしているかららしいけど…ユーザーが置いてきぼりになってる感がスゴイ(汗)

とりあえず最新が良いわけだろうし、なんとかなるべ。

で、早速設置。
そしてひと苦労。

V5シリーズからはファイルセットはlibフォルダーに入ってます。
で、これをwordpressのどこに置いても良いようですが、まあ管理しやすさと子テーマまでのフォルダを拾ってくれる関数があるから使用テーマの下に設置します。( /wp-content/themes/99999/lib ってことね)
wordpress側のheadタグに書き込んで(やり方については検索すればすぐに出てくるので割愛)おおよそ終わり。
引っかかってたのは、ググると多くの説明ではグーグルのAPIキーやカレンダーIDをそのまま書き込めって書いてある。
いや、それはまずいっしょ。セキュリティガバガバ過ぎね?
一応一見して見れないように別ファイルにして読み込むようにしましょう。
設定を書いて、適当にファイル名つけて、先程のlibフォルダーに入れます。もちろんheadタグ内にリンクをつけるのを忘れずに♪
※グーグルAPIキーの取得やカレンダーIDの取得は調べるとすぐに出るので割愛します…(ちゃんと説明する自信がないだけデス)

とりあえずドノーマルで表示してみよう。
はい、表示されなーい(汗)

<ここから沼>
調べるとその宣言方法がいろいろ出てくる。しかもちょっとしか違いがわからないものもある。
ってことで、本家のリファレンスを確認。んーん。英語(T_T)

リファレンスから宣言部分をコピーしてきて件のファイルに入れ直す。(差分がなにか見るの忘れた…きっと忘れた頃にもう一回この沼に入ることになるでしょう…)

おお、表示されたよ。よかった(ここまでで約3時間)

さて、ここからカスタマイズです。

まずは日本語表記。
そして月曜始まり。
カレンダーのヘッダーをいぢる。(前の月、今日、次の月のボタンが左ブロック、年月がセンター、月表示とリスト表示の切り替えを右ブロック)
この辺はv4シリーズと同じだったのですぐできました♪

で、一旦確認。
おっと、各日の数字の後ろに「日」がついてる。うざい。
これもv4シリーズの手法が使えます。

さて、予定のある日の挙動は…
え!グーグルカレンダーに飛ぶの!?
えーーーーーー。
まあこれはカレンダー準拠の機能っぽいな。どっかに飛ばさせない設定とかないかね…
ないのかね…。
あらそう。どうするよ(汗)

2日間かけて、合計ほぼ5時間ほど調べた結果、v4シリーズでこれに対応している記事を見つけましたが、どうもv5に適用できません。いや、俺が理解できてないからかもしれません!いやきっとそうです!(T_T)

ので、本家リファレンスを参考に、イベントをクリックするとアラートで表示するように改造しました。
アラートと言ってもエラーっぽくならないように「クリックした内容は営業開始時間と終了時間ですよ」という感じに表示します。

クリックしたイベントデータを直接書いたら、とんでもない数字が並んでしまった(Date形式)ので、日付を調整してくれる moment.js を導入しました。
このリンク先から moment.js をダウンロードしてきて、さっきのlibにアップロード。そしてwordpressのheadタグにリンクを追加します。

さて、整形した文章をアラートに渡してっと。
じゃあ確認。
はい。表示されなーい。(T_T)

表示されなかった原因は、まあよくありがちなセミコロン付け忘れでした…
修正ついでに、分かりづらい書き方だったので、変数を作って見やすいようにしときましょう。
おー良かった動く!
そしてアラートも…なんとなくブサイクだけど、まあとりあえずこれで良いかな。

次に気になったのはカレンダーの表示が多すぎること。デフォだと6週分が常に表示されています。
またもググると「day:31」を入れればいいとのこと。
なんだ簡単じゃ~ん…はい。v4シリーズまででーす。

v5では「duration: {day:31}」と書くそうです。
がしかし「現在から31日間」ということになるようです。試しませんでしたが、ちょっと違うかな…
で、またも本家リファレンスを漁ると…あった!
「 fixedWeekCount: false 」で、自動調整してくれるようになりました。(tureがデフォ)
これで4週なら4段、6週なら6段と勝手に変えてくれます。

そうしてできたのが以下のコードです。
同じように悩むことがあれば、試してみてください♪




【FullCalendar 5.5.1 仮称設定ファイル】
ファイル名は何でも良いようです。libに格納してください。headタグ内で呼び出しを忘れずに。

document.addEventListener('DOMContentLoaded', function() {
 var calendarEl = document.getElementById('calendar');
 var calendar = new FullCalendar.Calendar(calendarEl, {
   initialView: 'dayGridMonth',
   // GoogleカレンダーのAPIキーを設定
   googleCalendarApiKey: '---自分のAPIキーを入れてね---',
   // カレンダーIDを設定
   events: '---使用するカレンダーIDを入れてね---',
   // 日本語化
   locale: 'ja',
   // 高さ自動調整
   height: 'auto',
   // ヘッダー部レイアウト
   headerToolbar: {
     left: 'prev,today,next',
     center: 'title',
     right: 'dayGridMonth,listMonth'
   },
   // 24時間表示
   eventTimeFormat: {
     hour: 'numeric',
     minute: '2-digit'
   },
   // 日本語化により各日付の後ろにつく「日」を取る
   dayCellContent: function(e) {
     e.dayNumberText = e.dayNumberText.replace('日', '');
   },
   // ボタン文字列の日本語化
   buttonText: {
     today: '今日',
     month: '月',
     week: '週',
     day: '日',
     list: 'リスト'
   },
   // all-day表示を終日にする
   allDayText: '終日',
   // デフォルトの6週間表示を自動調整
   fixedWeekCount: false,
   // イベントをクリックしたらグーグルカレンダーへ飛ばずアラート表示
   eventClick: function(info) {
     var eventObj = info.event;
     if (eventObj.allDay == false) {
       var daytext = moment(eventObj.start).format('YYYY-MM-DD');
       var starttext = moment(eventObj.start).format('HH:mm');
       var endtext = moment(eventObj.end).format('HH:mm');
       if (eventObj.url) {
         alert( '【'+ daytext +'】\n開店 ' + starttext + ' 〜 閉店 ' + endtext );
       }
       } else {
         alert( '【'+ daytext +'】\n' + eventObj.title);
       } info.jsEvent.preventDefault();
     },
   });
   calendar.render();
});

【CSS】
CSSはこちら。色は可愛い系だから適宜変えてください。
使用テンプレートのstyle.cssに追加しておきます。

// 各日のヘッダー背景色 
.fc-daygrid-day-top { background-color: #f4ffff; } 
// 本日のヘッダー背景色 
.fc-day-today .fc-daygrid-day-top { background-color: #fddcab; } 
// 各日のイベント背景色 
.fc-daygrid-day-frame { background-color: #f3f3f3; } 
// 曜日ヘッダーと各日の変な隙間を消す 
table.fc-scrollgrid-sync-table { margin: 0 0 20px 0; } 
// 曜日ヘッダーの変な隙間を消す 
table.fc-col-header { margin: 0; } 
// 土曜日のヘッダー背景色 
th.fc-day-sat { background-color: #eaf4ff; } 
// 日曜日のヘッダー背景色 
th.fc-day-sun { background-color: #ffeaea; } 
// ツールバー内の日付を他の h2 より小さくしたかった 
.fc .fc-toolbar-title { font-size: 1.5em; padding: 5px 10px 0px; }

もちろんこれが正解ではないと思います。(検証してないので自信ないッス!)
正直「動くから良いか」という感じ。
まあそんなものでも、何かの役に立てば幸いです。

では〜(・∀・)