前回
本題
今回は現在時刻をJSで更新して表示するプラグインをつくります。
ファイル名は「datetime.inc.php」とします。
設計
&datetime([表示形式],[UNIX時間]);
- &datetime(
y-m-d h:i:s
); という形で呼び出すと「2024-12-17 16:27:32」という風に表示 - フォーマットの指定がされていないときはデフォルトで「
y-m-d h:i:s
」 - UNIX時間が表示されていないときはデフォルトで現在時刻に (ぶっちゃけ必要ではないかも)
- UNIX時間に -1 を指定することで現在時刻となる (表示形式のみ指定したらいい話なので勝手に内部で-1になる)
開発
<?php
function plugin_datetime_inline() {
// 引数を取得
$args = func_get_args();
// フォーマットとUNIX時間を取得、三項演算子で存在しない場合はデフォルトにしておく
// (-1 は現在時刻を使用するためのフラグ的なもの)
$format = !empty($args[0]) ? htmlsc($args[0]) : 'y-m-d h:i:s';
$unixtime = !empty($args[1]) ? htmlsc($args[1]) : "-1";
// UNIX時間が指定されていればその時間を使用
// date() でフォーマットを適用して表示
$date = get_date($format, $unixtime == "-1" ? time() : $unixtime);
return <<<EOD
<span class="plugin_datetime">
<span>{$date}</span>
<input type="hidden" class="plugin_datetime_property" value="{"format":"{$format}","unixtime":{$unixtime}}" />
</span>
EOD;
}
function plugin_datetime_init() {
global $head_tags;
$head_tags[] = <<<EOD
<script>
function plugin_datetime_update() {
document.querySelectorAll(".plugin_datetime").forEach((tag) => {
let prop = JSON.parse(tag.querySelector(".plugin_datetime_property").value);
let format = prop.format;
let unixtime = prop.unixtime;
if (unixtime != "-1") return;
let date = new Date();
let y = date.getFullYear();
let m = ('0' + (date.getMonth() + 1)).slice(-2);
let d = ('0' + date.getDate()).slice(-2);
let h = ('0' + date.getHours()).slice(-2);
let i = ('0' + date.getMinutes()).slice(-2);
let s = ('0' + date.getSeconds()).slice(-2);
// フォーマットを適用する
let formatted = format.replace(/y/g, y).replace(/m/g, m).replace(/d/g, d).replace(/h/g, h).replace(/i/g, i).replace(/s/g, s);
// 時刻の書き換え
tag.querySelector("span").innerHTML = formatted;
});
}
setInterval(plugin_datetime_update, 1000); // 1秒ごとに更新 1s = 1000ms
</script>
EOD;
}
plugin_datetime_inline() 関数
&datetime([表示形式],[UNIX時間]);で呼び出される
-
1番目の引数を表示形式、2番目の引数をUNIX時間として取得
- PukiWikiプラグインでは一般的に可変長引数を扱うため、func_get_args() で引数を取得する
-
表示形式の引数がない場合は 'y-m-d h:i:s' を、UNIX時間の引数がない場合は現在時刻を使う
-
get_date() はPukiWiki内部のfunc.phpで定義されている関数で、PHP標準関数と違ってPukiWikiの設定に沿って日付を取得できる
-
htmlsc() もPukiWiki内部の関数で、HTMLエスケープを行う、これしないとXSSされる可能性がある
-
返り値はHTML、spanで囲んで表示形式に従って日付を表示するという仕組み
- spanの中に、UNIX時間と表示形式をjson形式でinput[type=hidden]で持たせる
- JavaScriptで1秒ごとに更新するために使う
- spanの中に、UNIX時間と表示形式をjson形式でinput[type=hidden]で持たせる
plugin_datetime_init() 関数
プラグインが呼び出された(plugin_datetime_inline() が呼び出された)ときに呼び出される
ブラウザ上で継続的に時刻を更新するためにJavaScriptをheadタグに追加する
- グローバル変数 $head_tags にJavaScriptを追加
- JSで1秒ごとに plugin_datetime_update() を呼び出して、ページ内の datetime クラスを持つタグの時刻を更新する
- JSON.parse() で input[type=hidden] のvalueに入ってるjsonを読み込める
- setInterval() で1秒ごとに plugin_datetime_update() を呼び出す
最後に
PukiWiki側で定義されている $html_tags というグローバル変数を使うことで、headタグにタグを追加することができます。
使いこなせば、JavaScriptを使った機能を追加することも可能なので便利です。