1 : 第1部:TacmicCMSの構造とテンプレートの役割

TacmicCMSにおけるPHPロジック、Smartyテンプレート、MariaDBデータの3層分離と基本アーキテクチャを学びます。

TacmicCMSは、堅牢なPHPバックエンドと高速なMariaDBデータベース、そして柔軟なSmartyテンプレートエンジンが有機的に結合したオープンソースCMSです。

💡 本ガイドの目的
本電子書籍(Smartyset)では、TacmicCMSおよびImpressCMSにおけるSmartyテンプレートの書き方、コア提供変数、修飾子、制御構文から、PHP 8.5環境での安全なコーディング作法までを体系的に網羅・詳解します。

3層分離アーキテクチャ(MVC思想)

TacmicCMSは、プログラムコード(PHP)の中にHTMLを直接混在させるのではなく、責務ごとに明確に分離されています。

この分離により、デザイン担当者とプログラム開発者が互いの作業を妨げることなく、安全かつ効率的にサイト構築やモジュール開発を行うことができます。

1 - 1 : TacmicCMSの全体構造とアーキテクチャ

リクエストから画面描画までのライフサイクル

訪問者がブラウザからURLにアクセスした際、TacmicCMSは以下のステップを経て画面を生成・出力します。

  1. mainfile.php のロード: データベース接続、サイトURL(XOOPS_URL)、物理パス(XOOPS_ROOT_PATH / XOOPS_TRUST_PATH)、セキュリティチェックを初期化。
  2. header.php のロード: セッション開始、ログインユーザー認証、有効なテーマ決定、Smartyテンプレートエンジン($xoopsTpl)のインスタンス化、配置されたブロックのデータ取得。
  3. モジュールの主処理(コントローラ): URLパラメータ(IDや検索条件)を受け取り、データベースから必要な情報を取得。テンプレートで使いたいデータを $xoopsTpl->assign() でSmartyへ引き渡し。
  4. Smartyのコンパイル&レンダリング: モジュールのテンプレートとテーマ(theme.html)を結合し、Smartyタグを高速なPHPコードへとコンパイル(templates_c にキャッシュ保存)。
  5. footer.php の出力: フッターブロックの処理、デバッグ情報の収集、最終的なHTMLをブラウザへ送出。
🚀 高速化の仕組み(テンプレートキャッシュ)
Smartyは毎回テンプレートファイルをパースするのではなく、初回実行時にPHPスクリプトへコンパイルして templates_c フォルダに保存します。2回目以降のアクセスではこのコンパイル済みPHPが直接実行されるため、ネイティブPHPとほぼ同等の超高速動作を実現しています。

1 - 2 : モジュール開発とテンプレートの関係

PHPからSmartyへデータを渡すassignメソッドと、テンプレート定義ファイルicms_version.phpの役割を解説します。

1. PHPからテンプレートへデータを渡す(assign)

PHP側で取得・加工したデータは、$xoopsTpl->assign() を呼び出してSmarty変数として登録します。

// 単一の値(文字列や数値)
$xoopsTpl->assign('page_title', '新着ニュース一覧');
$xoopsTpl->assign('item_count', 42);

// 連想配列(レコード1件分)
$topic = [
    'id' => 101,
    'title' => 'TacmicCMS 2.0 リリース!',
    'date' => '2026-11-02'
];
$xoopsTpl->assign('topic', $topic);

// 多次元配列(ループ表示用のリスト)
$articles = [];
while ($row = $db->fetchArray($result)) {
    $articles[] = $row;
}
$xoopsTpl->assign('articles', $articles);

2. 表示するテンプレートを指定する($xoopsOption)

モジュールのメイン画面を表示する場合、header.php をインクルードする前に $xoopsOption['template_main'] を指定します。

<?php
include_once "header.php";

// このページで使用するSmartyテンプレートファイル名を指定
$xoopsOption['template_main'] = "d3news_index.html";

include_once XOOPS_ROOT_PATH . "/header.php";

// ... モジュールのロジック処理 ...

include_once XOOPS_ROOT_PATH . "/footer.php";
?>

3. テンプレートの事前登録(icms_version.php / xoops_version.php)

モジュール内で使用するテンプレートは、モジュールの定義ファイル icms_version.php(または xoops_version.php)に宣言しておく必要があります。管理画面でのテンプレートセット管理(ALTSYS等)やDBへの取り込みに必須です。

$modversion['templates'][] = [
    'file' => 'd3news_index.html',
    'description' => 'ニュース一覧トップページ'
];
$modversion['templates'][] = [
    'file' => 'd3news_article.html',
    'description' => 'ニュース記事詳細ページ'
];

2 : 第2部:Smartyテンプレートの基本構文と作法

TacmicCMSにおけるSmartyデリミタ、コメント記法、波括弧競合を防ぐリテラルタグの正しい使い方を習得します。

Smartyテンプレートは、通常のHTMLの中に デリミタ(区切り記号) で囲まれたSmartyタグを埋め込むことで動作します。

TacmicCMSでは、Web標準のHTML5/CSS/JavaScriptと安全に共存できるように設計されたデリミタルールが採用されています。

2 - 1 : デリミタ(区切り文字)と基本ルール

TacmicCMS推奨デリミタ <{ }> とコメント構文 <{* *}> の安全性について詳解します。

TacmicCMSの標準デリミタ:<{ と }>

標準的なSmartyでは { ... }(波括弧)がデリミタとして使われることが多いですが、TacmicCMSおよびXOOPS/ImpressCMS系では <{ と }> が標準採用されています。

⚠️ なぜ <{ ... }> を使うのか?
HTML内のインラインスタイル(CSS)やJavaScriptでは { font-size: 14px; } や function() { ... } のように波括弧が頻繁に登場します。デリミタが単なる { } だと、SmartyがCSSやJSの波括弧を変数や関数と誤認してパースエラー(構文エラー)を起こしてしまいます。
<{ ... }> を使うことで、CSSやJavaScriptとの不要な衝突を自然に回避できます。

テンプレート内コメント:<{* ... *}>

テンプレート内に制作メモやロジックの説明を残したい場合は、Smartyコメントタグを使用します。

<{* ここは管理者向け専用エリアです。一般ユーザーには非表示 *}>
<{if $icms_isadmin}>
    <div class="admin-panel">管理用リンク</div>
<{/if}>
コメント種別 書き方 HTMLソースに出力されるか? 用途・安全性
Smartyコメント <{* コメント内容 *}> 一切出力されない 社内メモ、仕様解説、非公開コード。ブラウザで見られないため安全。
HTMLコメント <!-- コメント内容 --> ブラウザにそのまま届く 「ページのソースを表示」で見えてしまうため、機密情報や内部仕様は書かないこと。

2 - 2 : リテラルタグ <{literal}> の重要性と活用法

JavaScript、jQuery、CSS、JSON-LD構造化データを安全に埋め込むためのテクニックを解説します。

リテラルタグとは?

<{literal}> と <{/literal}> で囲まれたブロックの中身は、Smartyエンジンによる解釈が完全に停止し、文字通り(Literal)そのまま出力されます。

インラインJavaScript / jQueryの埋め込み

<{literal}>
<script>
document.addEventListener("DOMContentLoaded", function() {
    const btn = document.querySelector("#submit-btn");
    btn.addEventListener("click", function(e) {
        alert("送信処理を実行します");
    });
});
</script>
<{/literal}>

JSON-LD(SEO用構造化データ)の埋め込み

Google検索結果のリッチスニペットで必須となるJSON-LDは波括弧が連続するため、必ず <{literal}> を活用します。

<script type="application/ld+json">
<{literal}>
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": <{/literal}>"<{$topic.title|escape:'javascript'}>"<{literal}>,
  "datePublished": <{/literal}>"<{$topic.published|date_format:'%Y-%m-%d'}>"<{literal}>
}
<{/literal}>
</script>
💡 リテラル内でSmarty変数を展開する小技
上記のように、リテラルブロックの途中で一度 <{/literal}> を閉じ、Smarty変数 <{$topic.title}> を出力した直後に再び <{literal}> を再開することで、複雑なJSONの中でも安全に変数を埋め込むことができます。

3 : 第3部:変数(Variables)とスコープ完全ガイド

テンプレート変数の参照法、スーパーグローバル変数、TacmicCMSコア提供変数、D3モジュール変数を徹底解説します。

Smartyにおける変数は先頭にドル記号 $ を付けます。PHPから渡されたデータだけでなく、スーパーグローバル変数やTacmicCMSが提供するコア変数にアクセスできます。

3 - 1 : テンプレート変数の基本とデータ構造の参照法

スカラー値、連想配列、添字配列、オブジェクトプロパティ・メソッドの参照記法を整理します。

データ構造に応じた参照記法

Smartyの記法 PHPでの相当コード 説明
<{$sitename}> $sitename 文字列、数値などの単純なスカラー変数を出力
<{$user.name}> $user['name'] 連想配列のキー 'name' の値を参照(ドット構文)
<{$list[0]}> $list[0] 数値インデックス配列の1番目の要素を参照
<{$item.category.title}> $item['category']['title'] 階層化された多次元連想配列を連続してドットで参照
<{$article->title}> $article->title オブジェクトのパブリックプロパティを参照
<{$article->getTitle()}> $article->getTitle() オブジェクトのメソッドを実行して返り値を参照

3 - 2 : Smarty予約変数(スーパーグローバルと環境変数)

$smarty.get, $smarty.post, $smarty.const, $smarty.now などの予約変数を網羅します。

Smarty組み込み予約変数($smarty.*)

PHP側でわざわざ assign しなくても、Smartyが初めから用意している特別な予約変数です。

Smarty予約変数 対応するPHPグローバル 解説・具体例
<{$smarty.get.id}> $_GET['id'] URLクエリパラメータ(例: ?id=5)の値を取得
<{$smarty.post.keyword}> $_POST['keyword'] フォームからPOST送信されたパラメータを取得
<{$smarty.session.userid}> $_SESSION['userid'] 現在のセッション変数に保持されている値を取得
<{$smarty.cookies.theme}> $_COOKIE['theme'] クライアントCookieの値を取得
<{$smarty.server.REQUEST_URI}> $_SERVER['REQUEST_URI'] 現在のアクセスパス・URLパスを取得
<{$smarty.now}> time() 現在のUNIXタイムスタンプ(後述の date_format 修飾子と併用)
<{$smarty.const.XOOPS_URL}> XOOPS_URL PHPの define() で定義された定数を直接参照
💡 コピーライト年号の自動更新テクニック
© <{$smarty.now|date_format:"%Y"}> TacmicCMS とテンプレートに書いておけば、毎年手動でテーマの年号を書き換える手間がゼロになります!

3 - 3 : TacmicCMS / ImpressCMS コア提供グローバル変数一覧

テーマやブロックで常に利用可能なシステム定義グローバル変数の完全一覧です。

テーマ(theme.html)およびブロックで利用できる主要変数

変数名 型 内容・用途
<{$icms_sitename}> string 一般設定で登録された「サイト名」
<{$icms_slogan}> string 一般設定で登録された「サイトのスローガン」
<{$icms_pagetitle}> string 現在のページタイトル(<title> タグで使用)
<{$icms_url}> / <{$xoops_url}> string サイトのルートURL(例: http://tcms.local)
<{$icms_imageurl}> string 現在適用されているテーマのURL(例: /themes/tacmic/)
<{$icms_themecss}> string テーマ標準CSSのURL(style.css)
<{$xoops_contents}> string 最重要:各モジュールがレンダリングしたメインHTMLが出力される位置
<{$xoops_module_header}> string モジュールが必要とするCSSやJavaScript(<head> 内に必須)
<{$icms_isuser}> bool ログイン中の一般ユーザーなら true
<{$icms_isadmin}> bool 管理者グループに所属しているなら true
<{$icms_uname}> string ログインユーザーのアカウント名(ハンドル名)
<{$icms_breadcrumbs}> array パンくずナビゲーション用の階層リンク配列

3 - 4 : D3モジュール特有の変数と環境変数

$mydirname や $mod_url など、D3モジュール複製時に活躍する必須変数を解説します。

D3モジュールの複製設計と <{$mydirname}>

D3(Duplicatable V3)アーキテクチャでは、1つのモジュール(例: d3chapter)をフォルダ名を変えて複製(例: smartyset, manual, book2)し、複数共存させることができます。

そのため、テンプレート内ではモジュールディレクトリ名を絶対にハードコードせず、必ず <{$mydirname}> を使用します。

<{* 悪い例:フォルダ名が固定されているため複製するとリンクが壊れる *}>
<a href="<{$xoops_url}>/m/d3chapter/content.php?lid=1">第1章へ</a>

<{* 良い例:現在のモジュール名が自動展開されるため完全にポータブル *}>
<a href="<{$mydirurl}>/content.php?lid=1">第1章へ</a>
<img src="<{$xoops_url}>/m/<{$mydirname}>/images/icon.png" alt="アイコン" />

D3テンプレートで共通利用可能な変数

4 : 第4部:変数の修飾子(Modifiers)徹底解説

Smartyが提供する文字列操作、日付変換、数値フォーマット、XSS対策エスケープ修飾子を実例付きで完全網羅します。

変数の修飾子(Modifier)とは、出力する直前に変数へ適用するフィルタ機能です。パイプ記号 | を使って指定します。

<{$変数名|修飾子:パラメータ1:パラメータ2}>

4 - 1 : 文字列操作・整形修飾子

lower, upper, capitalize, cat, truncate, strip_tags などの実用例です。

文字列整形修飾子一覧

修飾子 構文例 機能と出力結果の例
lower <{$str|lower}> 英字をすべて小文字に変換(HELLO → hello)
upper <{$str|upper}> 英字をすべて大文字に変換(hello → HELLO)
capitalize <{$str|capitalize}> 単語の先頭を大文字化(tacmic cms → Tacmic Cms)
cat <{$name|cat:" 様"}> 文字列の末尾に指定テキストを連結(久岡 → 久岡 様)
truncate <{$text|truncate:60:"..."}> 指定文字数で丸め、末尾に省略記号を付与(一覧サマリー表示に多用)
strip_tags <{$html|strip_tags}> HTMLタグ(<p>等)をすべて除去して純粋なテキストのみを抽出
replace <{$text|replace:"XOOPS":"TacmicCMS"}> 指定文字列を別の文字列へ置換

4 - 2 : 日付・数値・フォーマット修飾子

date_format, number_format, string_format の詳細なフォーマット指定子を解説します。

1. date_format(日付・時刻フォーマット)

UNIXタイムスタンプを任意の年月日時分秒形式に整形します。CMSで最も頻繁に使われる修飾子です。

<{* 年月日と時分を表示 *}>
<{$article.posted|date_format:"%Y年%m月%d日 %H:%M"}>
<{* 出力例: 2026年11月02日 16:30 *}>

<{* ハイフン区切りの短い日付 *}>
<{$article.posted|date_format:"%Y-%m-%d"}>
<{* 出力例: 2026-11-02 *}>
指定子 説明 出力例
%Y4桁の西暦2026
%m2桁の月(01〜12)11
%d2桁の日(01〜31)02
%H24時間制の時(00〜23)16
%M2桁の分(00〜59)30
%S2桁の秒(00〜59)00

2. number_format(数値・金額のカンマ区切り)

<span class="price"><{$product.price|number_format}> 円</span>
<{* 2300000 → 2,300,000 円 *}>

3. string_format(ゼロ埋めフォーマット)

<{* 4桁ゼロパディング(コード番号やID管理に便利) *}>
<{$user.id|string_format:"%04d"}>
<{* 5 → 0005 *}>

4 - 3 : セキュリティ・安全性修飾子(escape, default, nl2br)

XSS脆弱性を防ぐescape、空データフォールバックdefault、改行反映nl2brの安全な併用パターンです。

1. escape(HTML/JavaScriptエスケープ:XSS対策)

外部からの入力値、投稿記事のタイトル、ユーザーのコメントなどを出力する際は、クロスサイトスクリプティング(XSS)を防ぐために必ず escape を通します。

<{* HTML特殊文字(< > & ")を安全にエンコード *}>
<h3><{$comment.title|escape}></h3>

<{* inputタグのvalue属性に安全に埋め込む場合 *}>
<input type="text" name="uname" value="<{$user.uname|escape:'html'}>" />

<{* JavaScript文字列の中に埋め込む場合 *}>
<script>
const userTitle = "<{$user.title|escape:'javascript'}>";
</script>

2. default(未定義・空値時の代替テキスト)

変数が null、空文字、未定義の場合に出力するデフォルト値を指定します。

<{* 説明文が空なら「説明はありません」を表示 *}>
<p><{$item.description|default:"説明はありません"}></p>

<{* ユーザーのアバター画像が未登録なら共通デフォルト画像を表示 *}>
<img src="<{$user.avatar|default:'/images/default_avatar.png'}>" alt="アバター" />

3. パイプ連結(複数修飾子の組み合わせ技)

修飾子は左から順にいくつでもパイプ | で繋げることができます。

<{* 1. HTMLエスケープして安全にした後、2. 改行を <br /> に変換する最強パターン *}>
<div class="body"><{$post.comment|escape|nl2br}></div>

<{* 1. HTMLタグを除去し、2. 80文字で省略し、3. 安全にエスケープ *}>
<p class="summary"><{$article.body|strip_tags|truncate:80:"..."|escape}></p>

5 : 第5部:制御構文と組み込み関数(Built-in Functions)

条件分岐 if/elseif/else、繰り返し foreach とその高度なループプロパティ、テンプレート分割 include を学びます。

Smartyには、PHPのように条件分岐や繰り返し処理、外部テンプレートの分割インクルードを行う組み込み関数が用意されています。

5 - 1 : 条件分岐(if, elseif, else)と演算子

完全な比較演算子・論理演算子対応表と、安全な値判定のベストプラクティスです。

条件分岐の基本構文

<{if $role == 'admin'}>
    <span class="badge admin">管理者</span>
<{elseif $role == 'editor'}>
    <span class="badge editor">編集者</span>
<{else}>
    <span class="badge guest">一般ユーザー</span>
<{/if}>

比較演算子・論理演算子対応表

記号 英語代替 構文例 意味
==eq$a == $b等しい
!=ne, neq$a != $b等しくない
>gt$a > $bより大きい
<lt$a < $bより小さい
>=gte, ge$a >= $b以上
<=lte, le$a <= $b以下
!not!$is_active否定(〜ではない)
&&and$a && $b論理積(かつ)
||or$a || $b論理和(または)
is even-$num is even偶数である
is odd-$num is odd奇数である

5 - 2 : 繰り返し処理(foreach)とループプロパティ

foreachの基本、name属性を使ったループ番号iterationやfirst/lastプロパティ、foreachelseを完全習得。

1. 基本構文と foreachelse

配列の全要素をループ処理します。配列が空(0件)のときのために <{foreachelse}> を用意しておくと便利です。

<{foreach from=$articles item="article" key="id"}>
    <div class="article-card">
        <h4><{$article.title}></h4>
        <p><{$article.summary}></p>
    </div>
<{foreachelse}>
    <p class="no-data">現在公開されている記事はありません。</p>
<{/foreach}>

2. ループプロパティ(name 属性の指定)

name="myloop" のように名前を付けると、ループの回数や最初/最後の判定が可能になります。

<ul>
<{foreach from=$ranking item="rank" name="rankLoop"}>
    <li class="<{if $smarty.foreach.rankLoop.first}>top-winner<{/if}>">
        第<{$smarty.foreach.rankLoop.iteration}>位: <{$rank.name}>
        (全<{$smarty.foreach.rankLoop.total}>人中)
    </li>
<{/foreach}>
</ul>
プロパティ 値 説明
.iteration 1, 2, 3... 1から始まる現在のループ番号(順位表示や番号付けに最適)
.index 0, 1, 2... 0から始まる現在のインデックス値
.first true / false ループの最初の要素なら true
.last true / false ループの最後の要素なら true(区切り線の制御に便利)
.total int ループする要素の総件数

5 - 3 : テンプレート分割とインクルード(include)

include file="db:..." によるパーツ共通化とパラメータ引き渡しを解説します。

パーツの共通化:<{include}>

ページネーションバー、カードUI、ソーシャルシェアボタンなど、複数箇所で使い回したい部品はサブテンプレートとして切り出し、include 関数で読み込みます。

<{* DBテンプレートセットに登録されたサブテンプレートをインクルード *}>
<{include file="db:d3news_article_card.html" article=$one_article}>
💡 db: プレフィックスの秘密
file="db:ファイル名" と指定すると、TacmicCMSはデータベース(tplfile テーブル)に登録されたテンプレートセット(ALTSYS等でカスタマイズ可能)を優先的に読み込みます。これにより、実ファイルを触らずに管理画面から安全にデザインを上書きできます。

6 : 第6部:TacmicCMSカスタム関数・プラグイン

assign, cycle, counter, html_options, resized_image など便利なテンプレート関数を紹介します。

Smarty本体およびTacmicCMSには、テンプレートの記述を簡潔にし、デザインの表現力を高めるカスタム関数プラグインが多数用意されています。

6 - 1 : 変数操作と装飾プラグイン(assign, cycle, counter)

テンプレート内での変数再定義、テーブル行のストライプ配色、カウンタ関数の使い方です。

1. assign(テンプレート内で変数を定義・変更)

<{* テンプレート内で一時的なフラグや値をセット *}>
<{assign var="has_special_discount" value=true}>
<{assign var="banner_class" value="promo-highlight"}>

<{if $has_special_discount}>
    <div class="<{$banner_class}>">特別割引セール開催中!</div>
<{/if}>

2. cycle(偶数・奇数のストライプ背景)

ループ内で呼び出すたびに、指定した値を交互に出力します。

<table>
<{foreach from=$users item="u"}>
    <tr class="<{cycle values='odd,even'}>">
        <td><{$u.id}></td>
        <td><{$u.uname}></td>
    </tr>
<{/foreach}>
</table>

3. counter(ループ内番号インクリメント)

<{* 1から始まり、呼ぶたびに1ずつ増える *}>
<span class="badge">No. <{counter start=1 skip=1}></span>

6 - 2 : フォーム生成ヘルパー(html_options, html_radios)

セレクトボックスやラジオボタンを連想配列から一発生成するSmarty標準関数の活用法です。

html_options(セレクトボックスの自動生成)

PHPから渡された連想配列から、<option> タグを一括自動生成します。現在選択されている値(selected)も自動で判定されます。

<select name="prefecture" id="prefecture">
    <{html_options options=$pref_list selected=$current_pref_id}>
</select>

html_radios(ラジオボタングループの自動生成)

<div class="radio-group">
    <{html_radios name="gender" options=$gender_options selected=$current_gender separator="  "}>
</div>

6 - 3 : TacmicCMS専用関数(resized_image)

TacmicCMSコアに搭載された高速リサイズ&WebP対応画像プラグインの使い方を解説します。

resized_image プラグイン(画像リサイズ&キャッシュ)

アップロードされた大きな画像ファイル(JPEG/PNG等)を、テンプレート上で指定したピクセルサイズに自動縮小し、キャッシュディレクトリへ出力するTacmicCMS独自プラグインです。

<{* 幅300px・高さ200pxに自動リサイズして表示 *}>
<img src="<{resized_image file=$article.image_path width=300 height=200}>" alt="<{$article.title|escape}>" />

7 : 第7部:テーマ(theme.html)設計とレスポンシブ化

サイト全体のデザインを統括するtheme.htmlの構造、必須タグ、3カラムから1カラムへのレスポンシブ制御を解説します。

モジュールのコンテンツは、最終的にテーマ(themes/テーマ名/theme.html)の骨格の中に流し込まれます。美しいテーマを設計するための基本ルールを学びます。

7 - 1 : theme.html の基本スケルトンと必須要素

HTML5 DOCTYPE、viewport、module_header、xoops_contentsの配置ルールです。

最小限のモダンHTML5スケルトン

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
    <title><{if $icms_pagetitle}><{$icms_pagetitle}> : <{/if}><{$icms_sitename}></title>
    
    <link rel="stylesheet" href="<{$icms_imageurl}>style.css">
    
    <{* モジュールが要求するCSS・JSを出力(必須!) *}>
    <{$xoops_module_header}>
</head>
<body>
    <header class="site-header">
        <h1><a href="<{$icms_url}>/"><{$icms_sitename}></a></h1>
    </header>

    <main class="site-main">
        <{* 各モジュールが生成したメインHTMLがここに挿入される(超重要!) *}>
        <{$xoops_contents}>
    </main>

    <footer class="site-footer">
        <p>&copy; <{$smarty.now|date_format:'%Y'}> <{$icms_sitename}></p>
    </footer>
</body>
</html>

7 - 2 : ブロック配置とレイアウト制御(カラムレイアウト)

サイドバーブロックの表示判定フラグと、CSSグリッド/フレックスボックスとの連携方法です。

サイドバー(左ブロック・右ブロック)の条件分岐

管理画面の「ブロック管理」でサイドバーにブロックが配置されているかどうかは、$xoops_showlblock(左)や $xoops_showrblock(右)の真偽値で自動判定できます。

<div class="layout-container <{if $xoops_showlblock}>has-left-sidebar<{else}>no-sidebar<{/if}>">

    <{* 左サイドバーが存在するときだけ描画 *}>
    <{if $xoops_showlblock}>
    <aside class="left-sidebar">
        <{foreach item=block from=$xoops_lblocks}>
            <section class="block-box">
                <h3 class="block-title"><{$block.title}></h3>
                <div class="block-content"><{$block.content}></div>
            </section>
        <{/foreach}>
    </aside>
    <{/if}>

    <article class="main-content">
        <{$xoops_contents}>
    </article>

</div>

8 : 第8部:D3モジュールのテンプレート管理とカスタマイズ(ALTSYS連携)

D3テンプレートの3段階優先順位メカニズムと、ALTSYSを使った安全なDBテンプレートカスタマイズ手順を解説します。

D3モジュールの最大の特徴は、サーバー上の実ファイルを一切書き換えることなく、管理画面(ALTSYS)からデータベース上でテンプレートを安全にカスタマイズできる点にあります。

8 - 1 : D3テンプレートの基本構造(3段階の優先順位)

DBテンプレート(選択中テーマ)→ defaultセット → trust_path実ファイルの探索フローです。

テンプレートの読み込み優先順位(フォールバック)

TacmicCMSがD3モジュールのテンプレートを読み込む際、以下の優先順位で探索します。

  1. 第1優先:現在選択中のテーマ用DBテンプレートセット
    例: themes/tacmic/ を使用中なら、DB内の tacmic テンプレートセット。
  2. 第2優先:標準(default)DBテンプレートセット
    モジュールインストール時にDBへ登録された default セット。
  3. 第3優先:trust_path 内の物理テンプレートファイル
    DBに存在しない、またはDBが空の場合は、trust_path/modules/モジュール名/templates/ のファイルが直接参照されます。
🛡️ モジュールアップデートでカスタマイズが消えない理由
モジュール本体のバージョンアップによって trust_path 内のファイルが更新されても、管理者がDB上でカスタマイズしたテンプレート(第1優先)はデータベースに安全に保持されるため、上書きされてデザインが消える心配がありません。

8 - 2 : ALTSYSでのテンプレート複製と編集テクニック

ALTSYSのテンプレート管理を使った安全な複製・編集・デバッグ手順をステップバイステップで解説します。

ALTSYSでの編集手順

  1. 管理画面 > ALTSYS(システム管理) > テンプレート管理 を開きます。
  2. default セットはベースとなる基本セットのため、直接編集せず、使用しているテーマ名(例: tacmic)のセットへ 「複製」 します。
  3. 複製したセット内の対象テンプレート(例: d3news_index.html)の 「編集」 をクリック。
  4. コードエディタでHTMLやSmartyタグを修正し、「更新」ボタンを押します。
  5. 更新した瞬間にコンパイルキャッシュ(templates_c)が自動で再生成され、即座にサイトのデザインへ反映されます。

9 : 第9部:PHP 8.5 時代の安全なSmartyコーディング作法

PHP 8.2〜8.5で厳格化された未定義配列キー警告や未定義変数のエラーを出さないモダンテンプレート手法です。

PHP 8.2以降、特にPHP 8.5環境では、未定義の変数や配列キーへのアクセスに対する警告(Warning)が厳格化されました。エラーを出さない安全なSmartyコーディング作法を学びます。

9 - 1 : Undefinedエラー(Warning/Fatal)を出さない書き方

empty(), isset(), default修飾子を活用した堅牢な条件判定パターン集です。

PHP 8.5での落とし穴:未定義キーの参照

古いテンプレートでよく見られた以下の書き方は、PHP 8.5環境で Undefined array key 警告の原因となります。

<{* 危険な例:$user['avatar'] が未定義だと Warning が発生する *}>
<{if $user.avatar != ''}>
    <img src="<{$user.avatar}>" />
<{/if}>

<{* 安全な例 1:!empty() を使用(未定義でも警告が出ない) *}>
<{if !empty($user.avatar)}>
    <img src="<{$user.avatar}>" />
<{/if}>

<{* 安全な例 2:default 修飾子を併用する *}>
<img src="<{$user.avatar|default:'/images/no_image.png'}>" />

安全なコーディングチェックリスト

9 - 2 : XSS防止とエスケープポリシー(総まとめ)

Webセキュリティの基本である出力エスケープのベストプラクティス総まとめです。

安全な出力のための原則

動的なWebサイトにおいて、セキュリティの最前線となるのがテンプレートです。以下の原則を徹底しましょう。

  1. ユーザー投稿データは常に |escape を通す: 掲示板、コメント、プロフィール、お問い合わせフォームなど、訪問者が入力した文字列を出力する箇所は例外なくエスケープします。
  2. URLパラメータも |escape:'url' を通す: <a href="search.php?q=<{$keyword|escape:'url'}>"> のように属性値に埋め込む場合はURLエンコードを行います。
  3. HTML許可フィールドと分離する: リッチテキスト(CKEditor等)で入力された信頼できる管理者の投稿のみHTML出力を許可し、一般ユーザーの投稿はテキスト形式(|escape|nl2br)に統一します。
🎉 TacmicCMS Smartyマスター!
本電子書籍(Smartyset)で解説したルールと作法を実践すれば、デザイン崩れがなく、PHP 8.5でも一切のエラーを出さない、高速・美麗・安全なWebサイトを自由自在に構築できるようになります!

1 第1部:TacmicCMSの構造とテンプレートの役割 Publish 1620 bytes 2026-11-02 16:15 by admin
1 - 1 TacmicCMSの全体構造とアーキテクチャ Publish 2171 bytes 2026-11-02 16:29 by サイト管理人
1 - 2 モジュール開発とテンプレートの関係 Publish 2223 bytes 2026-11-02 16:15 by admin
2 第2部:Smartyテンプレートの基本構文と作法 Publish 354 bytes 2026-11-02 16:15 by admin
2 - 1 デリミタ(区切り文字)と基本ルール Publish 3275 bytes 2026-11-02 16:15 by admin
2 - 2 リテラルタグ <{literal}> の重要性と活用法 Publish 1881 bytes 2026-11-02 16:15 by admin
3 第3部:変数(Variables)とスコープ完全ガイド Publish 252 bytes 2026-11-02 16:15 by admin
3 - 1 テンプレート変数の基本とデータ構造の参照法 Publish 2748 bytes 2026-11-02 16:15 by admin
3 - 2 Smarty予約変数(スーパーグローバルと環境変数) Publish 3752 bytes 2026-11-02 16:15 by admin
3 - 3 TacmicCMS / ImpressCMS コア提供グローバル変数一覧 Publish 4791 bytes 2026-11-02 16:15 by admin
3 - 4 D3モジュール特有の変数と環境変数 Publish 1680 bytes 2026-11-02 16:15 by admin
4 第4部:変数の修飾子(Modifiers)徹底解説 Publish 308 bytes 2026-11-02 16:15 by admin
4 - 1 文字列操作・整形修飾子 Publish 3224 bytes 2026-11-02 16:15 by admin
4 - 2 日付・数値・フォーマット修飾子 Publish 2893 bytes 2026-11-02 16:15 by admin
4 - 3 セキュリティ・安全性修飾子(escape, default, nl2br) Publish 2066 bytes 2026-11-02 16:15 by admin
5 第5部:制御構文と組み込み関数(Built-in Functions) Publish 194 bytes 2026-11-02 16:15 by admin
5 - 1 条件分岐(if, elseif, else)と演算子 Publish 4456 bytes 2026-11-02 16:15 by admin
5 - 2 繰り返し処理(foreach)とループプロパティ Publish 3335 bytes 2026-11-02 16:15 by admin
5 - 3 テンプレート分割とインクルード(include) Publish 1132 bytes 2026-11-02 16:15 by admin
6 第6部:TacmicCMSカスタム関数・プラグイン Publish 209 bytes 2026-11-02 16:15 by admin
6 - 1 変数操作と装飾プラグイン(assign, cycle, counter) Publish 1225 bytes 2026-11-02 16:15 by admin
6 - 2 フォーム生成ヘルパー(html_options, html_radios) Publish 779 bytes 2026-11-02 16:15 by admin
6 - 3 TacmicCMS専用関数(resized_image) Publish 879 bytes 2026-11-02 16:15 by admin
7 第7部:テーマ(theme.html)設計とレスポンシブ化 Publish 246 bytes 2026-11-02 16:15 by admin
7 - 1 theme.html の基本スケルトンと必須要素 Publish 1230 bytes 2026-11-02 16:15 by admin
7 - 2 ブロック配置とレイアウト制御(カラムレイアウト) Publish 1135 bytes 2026-11-02 16:15 by admin
8 第8部:D3モジュールのテンプレート管理とカスタマイズ(ALTSYS連携) Publish 265 bytes 2026-11-02 16:15 by admin
8 - 1 D3テンプレートの基本構造(3段階の優先順位) Publish 1526 bytes 2026-11-02 16:15 by admin
8 - 2 ALTSYSでのテンプレート複製と編集テクニック Publish 871 bytes 2026-11-02 16:15 by admin
9 第9部:PHP 8.5 時代の安全なSmartyコーディング作法 Publish 257 bytes 2026-11-02 16:15 by admin
9 - 1 Undefinedエラー(Warning/Fatal)を出さない書き方 Publish 1308 bytes 2026-11-02 16:15 by admin
9 - 2 XSS防止とエスケープポリシー(総まとめ) Publish 1539 bytes 2026-11-02 16:15 by admin