baserCMS 5系で管理画面一覧を拡張する実装方法
イベントで実装する showHead / showRow 実践例
はじめに
baserCMS は、CakePHP ベースの国産CMSで、企業サイトやオウンドメディア運用で使いやすい管理画面と拡張性が特徴です。
本記事では、baserCMS 5系のカスタマイズ実装例として、管理画面のブログ記事一覧に列を追加する方法を紹介します。
具体的には、管理画面テンプレートのオーバーライドではなく、BcListTable.showHead / BcListTable.showRow イベントを使って拡張するパターンです。
以降のコードは、すべて baserCMS 5系を前提にした実装例です。
対象
- baserCMS 5 でプラグイン開発している人
- 管理画面拡張と設定管理を整理したい人
- 運用時のエラーを減らしたい人
この記事で扱うこと
- 管理画面オーバーライドを避ける理由
-
showHead/showRowの最小実装 - 一覧末尾に投稿時刻列を追加する実践版サンプル
- 実装時に押さえるべきポイント
なぜオーバーライドではなくイベントなのか
管理画面テンプレートを直接オーバーライドすると、次の課題が出やすくなります。
- 本体アップデート時の差分追従コストが高い
- 他プラグインとの干渉リスクが上がる
- 不具合時の責務境界が曖昧になる
一方、イベント拡張なら、変更をリスナーに閉じ込められます。
その結果、保守性とアップデート耐性を両立しやすくなります。
最小実装サンプル
まずは、一覧に1列追加する最小構成です。
<?php
declare(strict_types=1);
namespace Example\Event;
use BaserCore\Event\BcHelperEventListener;
use BaserCore\Utility\BcUtil;
use Cake\Event\EventInterface;
class ExampleHelperEventListener extends BcHelperEventListener
{
public $events = [
'BcListTable.showHead',
'BcListTable.showRow',
];
public function bcListTableShowHead(EventInterface $event): void
{
if (!BcUtil::isAdminSystem()) return;
if ($event->getData('id') !== 'BlogPosts.Index') return;
$fields = $event->getData('fields') ?? [];
$fields[] = 'カスタム列';
$event->setData('fields', $fields);
}
public function bcListTableShowRow(EventInterface $event): void
{
if (!BcUtil::isAdminSystem()) return;
if ($event->getData('id') !== 'BlogPosts.Index') return;
$data = $event->getData('data');
if (!$data || empty($data->id)) return;
$html = '<span>Post ID: ' . (int)$data->id . '</span>';
$fields = $event->getData('fields') ?? [];
$fields[] = $html;
$event->setData('fields', $fields);
}
}
投稿時刻表示の実践版
ここでは、ブログ記事一覧の末尾に投稿時刻を H:i:s 形式で表示する列を追加する実装例を記述します。
BcListTable.showHead / BcListTable.showRow の fields は追加分の列データを積むための配列なので、このサンプルでは既存列の途中ではなく末尾に列を追加します。
EventListener 側(列追加 + 時刻表示)
<?php
declare(strict_types=1);
namespace BlogPostIndexAddTime\Event;
use BaserCore\Event\BcHelperEventListener;
use BaserCore\Utility\BcUtil;
use Cake\Event\EventInterface;
use Cake\I18n\FrozenTime;
class BlogPostIndexAddTimeHelperEventListener extends BcHelperEventListener
{
public $events = [
'BcListTable.showHead',
'BcListTable.showRow',
];
public function bcListTableShowHead(EventInterface $event): void
{
if (!BcUtil::isAdminSystem()) return;
if ($event->getData('id') !== 'BlogPosts.Index') return;
$fields = $event->getData('fields') ?? [];
$fields[] = '投稿時刻';
$event->setData('fields', $fields);
}
public function bcListTableShowRow(EventInterface $event): void
{
if (!BcUtil::isAdminSystem()) return;
if ($event->getData('id') !== 'BlogPosts.Index') return;
/** @var \BcBlog\Model\Entity\BlogPost $data */
$data = $event->getData('data');
if (!$data || empty($data->id)) return;
$posted = $data->posted;
if ($posted instanceof FrozenTime) {
$time = $posted->format('H:i:s');
} elseif ($posted) {
$timestamp = strtotime((string)$posted);
$time = $timestamp === false ? '' : date('H:i:s', $timestamp);
} else {
$time = '';
}
$html = $time !== '' ? '<span>' . h($time) . '</span>' : '<span>-</span>';
$fields = $event->getData('fields') ?? [];
$fields[] = $html;
$event->setData('fields', $fields);
}
}
実装時のチェックポイント
- 対象画面判定を必ず入れる(
BlogPosts.Index) - 管理画面以外では処理しない(
BcUtil::isAdminSystem()) -
postedはFrozenTime、文字列、空値を考慮して表示する - 日時変換に失敗した場合の表示値を決めておく(例:
-) -
showHead/showRowのfieldsは追加列用なので、既存列の途中挿入が必要なら別アプローチも検討する
まとめ
baserCMS 5系で管理画面一覧を拡張するなら、まずイベント差し込みを検討するのがおすすめです。
オーバーライドに比べて、更新追従・保守性・責務分離の面で安定した実装にしやすくなります。
尚、今回紹介した管理画面一覧に投稿時刻を追加表示する技術を応用したプラグインを近日 baserCMSマーケット に公開する予定です。
公開後は、そちらもぜひ参考にしてください。