ver.2.18 にて PHPが利用できるようになりました。
PHP が使えるようになったということで試しにカレンダーを作ってみました。
ver.2 では、PHP + Thymeleaf なので、使い方の参考になれば。
当月のみ表示のカレンダー
まず、当月のみ表示するカレンダーを作ります。
Thymeleaf の経験が少ないので、PHP 側でデータ成形を行います。
<?php
// 日付情報をセットし、Thymeleaf に渡す。
$year = date('Y');
$month = date('n');
$day = date('d');
$date = array(
'year' => $year,
'month' => $month,
'day' => $day,
);
$SPIRAL->setTHValue("date", $date);
//当月1日をタイムスタンプとして取得
$unixmonth = mktime(0, 0, 0, $month, 1, $year);
// 曜日情報をセットし、Thymeleaf に渡す。
$week = array('日', '月', '火', '水', '木', '金', '土');
$SPIRAL->setTHValue("week", $week);
// カレンダー用データ生成データ生成
$calendarBoxNum = array();
$boxNum = 1;
$rowNum = 1;
// 当月1日の曜日の番号を取得し、1日以前の日付をマイナスとして扱う
// 当月1日の週初めから末日の土曜日まで枠を作る
for ($count = - (date('w', mktime(0, 0, 0, $month, 1, $year)) - 1); $count < 100; $count++) {
// 1以上 当月数以内であれば配列にセット
if (1 <= $count && $count <= date('t', $unixmonth)) {
$calendarBoxNum[$rowNum][] = $count;
} else {
// マイナスなどの月の値でないものは枠を生成
$calendarBoxNum[$rowNum][] = "";
}
// 末日を超えているかつ、末日の土曜日となった場合に終了
if (date('t') <= $count && ($boxNum % 7) == 0) {
break;
}
// 7 日分のデータがセットされた場合次のボックスへ
if (($boxNum % 7) == 0) {
$rowNum++;
}
$boxNum++;
}
// カレンダーのデータをThymeleaf に渡す。
$SPIRAL->setTHValue("calendarBoxNum", $calendarBoxNum);
?>
続いて、HTML(Thymeleaf) 側で受けとったカレンダーのデータを出力します。
動作確認のため、デザインはあてていません。(bootstrap の CSS のみ読み込んでいます。)
<!-- bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<div class="sp-free-content-container-12" style="width: 80%;margin: 50px auto;">
<!-- 正しくPHP のデータを受け渡せている場合に表示 -->
<th:block th:if="${cp.result.value['error'] != true}">
<!-- 当月の表示 -->
<h3 class="mb-5" style="text-align: center;">
<span th:text="${cp.result.value['date']['year']}"></span>年 <span th:text="${cp.result.value['date']['month']}"></span>月
</h3>
<!-- カレンダー -->
<table class="table table-bordered">
<!-- 曜日表示 -->
<tr>
<div th:each="week:${cp.result.value['week']}">
<th th:text="${week}">曜日</th>
</div>
</tr>
<!-- 1週間毎にまとめられている配列を回す。 -->
<tr th:each="w:${cp.result.value['calendarBoxNum']}">
<!-- 枠の中に日付を表示 日付が本日の場合、クラスを追加 -->
<td th:each="d:${w.value}" th:text="${d}" th:classappend="${d} eq ${cp.result.value['date']['day']} ? bg-warning"></td>
</tr>
</table>
</th:block>
</div>
前月・翌月に移動できるカレンダー
次に前月・翌月に移動できるカレンダーを作ります。
URLパラメータに 年・月 をつける形を想定して、進めます。
<?php
// パラメータに年月の情報があるかチェック
if($SPIRAL->getParam("y") && $SPIRAL->getParam("m")){
// パラメータに記載の年月のデータをセット
$year = $SPIRAL->getParam("y");
$month = $SPIRAL->getParam("m");
$day = date('d');
//パラメータの年月が不正の場合処理終了
if(!checkdate($month, 1, $year)) {
$SPIRAL->setTHValue("error",true);
}
}else{
// パラメータがないもしくは、片方の場合は、当月をのデータをセット
$year = date('Y');
$month = date('n');
}
// 当月のカレンダーチェックの場合、本日の日付をセット
if(strtotime(date('Y-n')) == strtotime(date($year.'-'.$month))) {
$day = date('d');
}else{
$day = "0";
}
// 前月・翌月の情報を取得も日付情報をセット
$unixmonth = mktime(0, 0 , 0, $month, 1, $year);
$date = array(
'year' => $year,
'month' => $month,
'day' => $day,
'prevY' => date('Y', strtotime('-1 month', $unixmonth)),
'prevM' => date('m', strtotime('-1 month', $unixmonth)),
'nextY' => date('Y', strtotime('+1 month', $unixmonth)),
'nextM' => date('m', strtotime('+1 month', $unixmonth)),
);
// 日付情報をThymeleaf に渡す。
$SPIRAL->setTHValue("date",$date);
// 曜日情報をセットし、Thymeleaf に渡す。
$week = array('日','月','火','水','木','金','土');
$SPIRAL->setTHValue("week",$week);
// カレンダー用データ生成
$calendarBoxNum = array();
$boxNum = 1;
$rowNum = 1;
// 当月1日の曜日の番号を取得し、1日以前の日付をマイナスとして扱う
$earlyWeek = - (date('w', mktime(0, 0, 0, $month, 1, $year)) - 1);
// 当月1日の週初めから末日の土曜日まで枠を作る
for ($count = $earlyWeek; $count < 100; $count++) {
// 1以上 当月数以内であれば配列にセット
if (1 <= $count && $count <= date('t', $unixmonth)) {
$calendarBoxNum[$rowNum][] = $count;
} else {
// マイナスなどの月の値でないものは枠を生成
$calendarBoxNum[$rowNum][] = "";
}
// 末日を超えているかつ、末日の土曜日となった場合に終了
if (date('t') <= $count && ($boxNum % 7) == 0) {
break;
}
// 7 日分のデータがセットされた場合次のボックスへ
if (($boxNum % 7) == 0) {
$rowNum++;
}
$boxNum++;
}
// カレンダーのデータをThymeleaf に渡す。
$SPIRAL->setTHValue("calendarBoxNum", $calendarBoxNum);
?>
前月・翌月のリンクを設置
カレンダー部分は同様のデータ形式のため、修正はありません。
<!-- bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<div class="sp-free-content-container-12" style="width: 80%;margin: 50px auto;">
<!-- 日付が不正の場合、エラーを表示 -->
<th:block th:if="${cp.result.value['error'] == true}">
<p>不正な日付です。</p>
</th:block>
<!-- 日付が正しい場合 -->
<th:block th:if="${cp.result.value['error'] != true}">
<h3 class="mb-5" style="text-align: center;">
<!-- 前月に戻るリンクを表示 -->
<a th:href="${pages['p0997'].path} + '?y=' + ${cp.result.value['date']['prevY']} + '&m=' + ${cp.result.value['date']['prevM']}"><</a>
<!-- 当月の表示 -->
<span th:text="${cp.result.value['date']['year']}"></span>年 <span th:text="${cp.result.value['date']['month']}"></span>月
<!-- 翌月に戻るリンクを表示 -->
<a th:href="${pages['p0997'].path} + '?y=' + ${cp.result.value['date']['nextY']} + '&m=' + ${cp.result.value['date']['nextM']}">></a>
</h3>
<!-- カレンダー -->
<table class="table table-bordered">
<!-- 曜日表示 -->
<tr>
<div th:each="week:${cp.result.value['week']}">
<th th:text="${week}">曜日</th>
</div>
</tr>
<!-- 1週間毎にまとめられている配列を回す。 -->
<tr th:each="w:${cp.result.value['calendarBoxNum']}">
<!-- 枠の中に日付を表示 日付が本日の場合、クラスを追加 -->
<td th:each="d:${w.value}" th:text="${d}" th:classappend="${d} eq ${cp.result.value['date']['day']} ? bg-warning"></td>
</tr>
</table>
</th:block>
</div>
ソースコードも添付しておきます。
不具合やもっとこうしたほうがいい等あれば、リクエストボードよりご指摘ください。