記事一覧のデータをJSONファイルで管理する
ブログ記事一覧のページは今までHTMLベタ打ちで更新していました。
<li class="list_item" data-category="gadget" data-tag='["レビュー"]'>
<span class="Gadget">Gadget</span>
<a href="https://miscnote.com/blog/20240814-entry-01/">GameSir Nova Liteを買いました</a>
<span class="pr color_red">NEW</span>
<time class="date">2024-08-14</time>
</li>
このような形の部分をコピーして修正するだけなので、簡単といえば簡単なのですが…
タイトルの前の「ラベル部分」もカテゴリに合わせて変更していたので、その修正が地味に大変…というか修正し忘れて間違えていることが時々ありました。
もう少し管理を楽にしようと思い、今回はこの「タイトル・カテゴリー・タグ・日付・URL」といったデータ部分をJSONファイルで管理できるようにしてみました。
ついでに、更新してから1ヶ月以内の記事にはNEWの文字を付けるようにしました(今まで手打ちで追加/削除してたので😅)
※今回も例によってchatGPTに提案・書いてもらったコードです。
外部ファイルの形式を決める
PHPファイルで読み込むデータ形式はいくつか候補がありました。
- JSON: 最も一般的で、ほとんどの用途で十分。
- XML: 階層的なデータを扱う場合に有用。
- CSV: シンプルなテーブルデータや大量データに適している。
- INI: 設定データなどの簡単なキー・バリューのペアに使用。
- PHPファイル: PHPで直接データを使う場合に便利。
chatGPTはすごいですね! PHPでの使用方法や記述例までまとめてくれました。
ひと通り見た結果、一番シンプルで管理しやすそうだったJSONを採用しました。
CSVも悪くないかなと思ったのですが、今回の場合「タグ」にデータが1つ~複数入る形だったので、基本的に1つの項目に1つのデータを管理するCSVには不向きかなーと思い断念しました。
VScodeではCSVデータを編集するためのプラグインもあるみたいなので、別の機会に使ってみたいなと思います。
JSONファイルを作成
JSONファイル(blogs.json)はこのような形にしています。
{
"_comment": "// ここにメモ書き //",
"blogs": [
{
"category": "gadget",
"tags": [
"レビュー"
],
"url": "https://miscnote.com/blog/20240814-entry-01/",
"title": "GameSir Nova Liteを買いました",
"date": "2024-08-14"
},
{
"category": "other",
"tags": [
"サイト作成",
"HTML"
],
"url": "https://miscnote.com/blog/20240721-entry-03/",
"title": "サーバー移行でデータベースが動かなくなった(解決済)",
"date": "2024-07-21"
},
・・・・・・・・
]
}
PHPファイルを修正
PHPファイルの方では、このような処理を追加しました。
コード(bodyタグより前)
// JSONファイルを読み込む
$jsonData = file_get_contents('blogs.json');
// JSONデータをPHPの配列に変換
$blogsData = json_decode($jsonData, true);
// エラーチェック
if (json_last_error() !== JSON_ERROR_NONE) {
echo 'JSONデコードエラー: ' . json_last_error_msg();
exit;
}
// _commentキーが存在する場合は削除(表示には使わない)
if (isset($blogsData['_comment'])) {
unset($blogsData['_comment']);
}
// blogsキーのデータを取得
$blogs = isset($blogsData['blogs']) ? $blogsData['blogs'] : [];
// 現在の日付を取得
$currentDate = new DateTime();
コード(ulタグ部分)
<ul class="list">
<?php foreach ($blogs as $blog): ?>
<?php
// 記事の日付をDateTimeオブジェクトに変換
$blogDate = new DateTime($blog['date']);
// 日付の差を計算
$interval = $currentDate->diff($blogDate);
// "New"ラベルを追加する条件(30日以内の場合)
$isNew = $interval->days <= 30 && $blogDate <= $currentDate;
// カテゴリと表示用ラベルの対応
$categoryLabels = [
'gadget' => 'Gadget',
'other' => 'Other',
'game' => 'Game'
];
// タグとラベルの対応(ゲームカテゴリ用)
$gameLabels = [
'Minecraft' => 'Minecraft',
'メガクアリウム' => 'Megaquarium'
];
// カテゴリに応じたラベルを決定
if ($blog['category'] === 'game') {
// タグに基づいて特定のラベルを設定(ゲームカテゴリ専用)
$categoryLabel = $categoryLabels[$blog['category']]; // デフォルトは "Game"
foreach ($blog['tags'] as $tag) {
if (isset($gameLabels[$tag])) {
$categoryLabel = $gameLabels[$tag];
break;
}
}
} else {
// ゲームカテゴリ以外の通常ラベル
$categoryLabel = isset($categoryLabels[$blog['category']]) ? $categoryLabels[$blog['category']] : '';
}
// タグをJSON形式でエンコード
$dataTags = json_encode($blog['tags'], JSON_UNESCAPED_UNICODE);
?>
<li class="list_item" data-category="<?php echo $blog['category']; ?>" data-tag='<?php echo $dataTags; ?>'>
<span class="<?php echo $categoryLabel; ?>"><?php echo $categoryLabel; ?></span>
<a href="<?php echo $blog['url']; ?>"><?php echo htmlspecialchars($blog['title']); ?></a>
<?php if ($isNew): ?>
<span class="pr color_red">NEW</span>
<?php endif; ?>
<time class="date"><?php echo $blog['date']; ?></time>
</li>
<?php endforeach; ?>
</ul>
カテゴリーは「Gadget・Other・Game」の3つなのですが、そのうちGameカテゴリで「Minecraft・メガクアリウム」タグがある記事だけ、専用のラベルが表示されるようにしています。
Gameカテゴリ内の専用ラベルが増える処理は、行を追加するだけなので簡単に実装できます。
今のところGameカテゴリの中の2つだけですが、GadgetやOtherの中でも専用ラベルが必要になったらコードを修正する予定です。
専用ラベルに専用CSSclassを当ててる設定になっているので、ラベルが増えていくと管理が大変になりそう… この辺りはもう少し簡潔にできそうな気がします。
JSONのコメント部分の処理
本当はJSONファイルではコメントアウトが出来ないのですが、_commentというキーを使い、PHPファイルの方で_commentを削除することでメモ書きとして利用できるようにしています。
HTMLのコメントアウトのように書けないかと思いchatGPTに代替案を求めたのですが、どれも大変そうだったので…(JSON5やJSONCなど) 一番シンプルそうなこの形を採用しました。必要なコメントも少しだけだったので。
// _commentキーが存在する場合は削除(表示には使わない)
if (isset($blogsData['_comment'])) {
unset($blogsData['_comment']);
}
PHP側の_commentキー削除はこの部分で行っています。
…とここまで書いて、この部分は別に無くても動くのでは?と思ったのですが、chatGPTに聞いてみたところ、
この部分を削除しても表示には影響しませんが、データに不要な情報が含まれることになります。動作に影響はないものの、データのクリーンアップとしてこの部分も残しておいた方が良いでしょう。
とのことだったので、一応残しています。
【追記】ダミーデータの処理
この記事を書き終わって、さっそくJSONファイルに記事データを追加しようとしたのですが、前回のデータをコピー貼り付け・修正では修正漏れが起こりそうだったので、ダミーデータを書いておいて、それを修正する形にしてみました。
毎回入力する必要がある部分に「xxxxxxxx」と記載します。
{
"category": "xxxxxxxx",
"tags": [
"xxxxxxxx"
],
"url": "https://miscnote.com/blog/xxxxxxxx-entry-01/",
"title": "xxxxxxxx",
"date": "xxxxxxxx"
},
PHPの方で、
// カテゴリーが "xxxxxxxx" の場合、スキップ
if ($blog['category'] === 'xxxxxxxx') {
continue;
}
という処理を <?php foreach ($blogs as $blog): ?> 内に追記しました。
最後に
JSONで管理→それに対応する形のPHPコードを作成までは簡単に出来たのですが、コメントアウトの部分で妙に時間を使ってしまいました。
今回は無理やりJSONファイルで対応しましたが、いずれJSON5やJSONCなども利用してみたいと思います。