PHPCMS V9のフロントエンドで記事一覧を出力する際、各記事の所属カテゴリ名を表示したいケースがあります。デフォルトの{pc:content action="lists"}タグでは、記事データにカテゴリID(catid)は含まれていますが、カテゴリ名(catname)は含まれていません。
データベースの構造上、記事テーブルとカテゴリテーブルは分離されているため、単純なテンプレート変数ではカテゴリ名を取得できません。以下は、キャッシュファイルを活用してカテゴリ名を取得・表示する実装方法です。
カテゴリキャッシュの構造
PHPCMSはカテゴリ情報をキャッシュファイルに保存しています。該当ファイルを確認すると、カテゴリIDをキーとした連想配列で全カテゴリ情報が格納されています。
// phpcms/caches/caches_commons/caches_data/category_content_1.cache.php の内容例
return array (
6 => array (
'catid' => '6',
'siteid' => '1',
'type' => '0',
'modelid' => '1',
'parentid' => '0',
'arrparentid' => '0',
'child' => '0',
'arrchildid' => '6',
'catname' => 'お知らせ', // ← 必要なカテゴリ名
'catdir' => 'news',
'url' => '/html/news/',
// ... その他の設定
),
8 => array (
'catid' => '8',
'catname' => '製品紹介',
// ...
),
);
タグクラスの拡張
記事一覧タグの処理クラスを修正し、返却データにカテゴリ名を追加します。
対象ファイル:phpcms/modules/content/classes/content_tag.class.php
まず、lists()メソッドの既存処理を確認します。
public function lists($data) {
$catid = intval($data['catid']);
if(!$this->set_modelid($catid)) return false;
// WHERE句の構築
if(isset($data['where'])) {
$sql = $data['where'];
} else {
$thumb = intval($data['thumb']) ? " AND thumb != ''" : '';
if($this->category[$catid]['child']) {
$catids_str = $this->category[$catid]['arrchildid'];
$pos = strpos($catids_str, ',') + 1;
$catids_str = substr($catids_str, $pos);
$sql = "status=99 AND catid IN ($catids_str)" . $thumb;
} else {
$sql = "status=99 AND catid='$catid'" . $thumb;
}
}
$order = $data['order'];
$result = $this->db->select($sql, '*', $data['limit'], $order, '', 'id');
// ← ここにカテゴリ名追加処理を挿入
return $result;
}
データベースクエリ実行後、以下の処理を追加します。
// カテゴリキャッシュの読み込み
$categoryCache = getcache('category_content_1', 'commons');
// 各記事にカテゴリ名を付加
foreach ($result as $index => $record) {
$currentCatid = $record['catid'];
$result[$index]['category_name'] = $categoryCache[$currentCatid]['catname'];
}
テンプレートでの呼び出し
修正後、フロントエンドテンプレートでは以下のようにカテゴリ名を出力できます。
{pc:content action="lists" catid="0" num="10" order="id DESC"}
{loop $data $item}
<div class="article-item">
<span class="category-badge">{$item['category_name']}</span>
<a href="{$item['url']}">{$item['title']}</a>
<time>{date('Y-m-d', $item['inputtime'])}</time>
</div>
{/loop}
{/pc}
複数サイト対応の注意点
サイトIDが1以外の場合、キャッシュファイル名が変わります。動的にサイトIDを取得する実装にすることで、マルチサイト環境にも対応できます。
// 現在のサイトIDを取得
$siteIdentity = get_siteid();
$cacheKey = 'category_content_' . $siteIdentity;
$categoryCache = getcache($cacheKey, 'commons');
実装のポイント
| 項目 | 説明 |
|---|---|
| キャッシュ活用 | データベースクエリを増やさず、既存キャッシュから情報取得 |
| 変数名の衝突回避 | 既存フィールドと区別しやすいcategory_nameを採用 |
| 互換性 | 既存のlistsタグ利用箇所に影響なし |