ADR-003 - 模板引擎
ADR-003:模板引擎 (Smarty)
Section titled “ADR-003:模板引擎 (Smarty)”XOOPS 採用 Smarty 模板引擎的架構決策記錄。
已接受 - XOOPS 2.0 以來的核心決策
演進中 - 計劃在 XOOPS 4.0 中遷移到 Smarty 4/5
XOOPS 需要一個可以:
- 將表現與業務邏輯分離
- 允許主題設計師在不了解 PHP 的情況下工作
- 支持模板繼承和包含
- 為性能提供緩存
- 啟用用戶可自定義的模板
- 支持國際化
flowchart TB subgraph "PHP 層" A[模塊控制器] B[模板變量] end
subgraph "Smarty 引擎" C[Smarty 核心] D[模板編譯器] E[緩存管理器] end
subgraph "模板" F[模塊模板] G[主題模板] H[塊模板] end
subgraph "輸出" I[編譯 PHP] J[緩存 HTML] K[最終 HTML] end
A --> B B --> C C --> D C --> E D --> F D --> G D --> H F --> I G --> I H --> I E --> J I --> K J --> K我們將使用 Smarty 作為模板引擎,因為:
1. 關注點分離
Section titled “1. 關注點分離”// PHP (控制器) - 業務邏輯$items = $itemHandler->getPublishedItems();$xoopsTpl->assign('items', $items);
// Smarty (視圖) - 表現// templates/items.tpl{* Smarty 模板 - 無 PHP 邏輯 *}<{foreach item=item from=$items}> <article> <h2><{$item.title}></h2> <p><{$item.summary}></p> </article><{/foreach}>2. XOOPS 分隔符
Section titled “2. XOOPS 分隔符”XOOPS 使用 <{ 和 }> 代替標準 { }:
{* 標準 Smarty *}{$variable}
{* XOOPS Smarty - 避免 JavaScript 衝突 *}<{$variable}>3. 模板層次結構
Section titled “3. 模板層次結構”graph TB A[主題主模板<br>theme.html] --> B[模塊模板<br>module_index.tpl] A --> C[塊模板<br>block_*.tpl] B --> D[部分模板<br>_header.tpl] B --> E[部分模板<br>_footer.tpl]
style A fill:#f9f,stroke:#333 style B fill:#9ff,stroke:#333 style C fill:#ff9,stroke:#3334. 模板存儲
Section titled “4. 模板存儲”- 數據庫:自定義模板存儲以便恢復
- 文件系統:模塊目錄中的原始模板
- 緩存:為性能編譯的模板
Smarty 配置
Section titled “Smarty 配置”// XOOPS Smarty 初始化$xoopsTpl = new XoopsTpl();
// 自定義分隔符$xoopsTpl->left_delim = '<{';$xoopsTpl->right_delim = '}>';
// 緩存$xoopsTpl->caching = XOOPS_TEMPLATE_CACHE;$xoopsTpl->cache_lifetime = 3600;
// 安全$xoopsTpl->security_policy = new Smarty_Security($xoopsTpl);$xoopsTpl->security_policy->php_functions = [];$xoopsTpl->security_policy->php_modifiers = ['escape', 'count'];使用的模板功能
Section titled “使用的模板功能”{* 簡單變量 *}<{$title}>
{* 對象屬性 *}<{$item.title}>
{* 帶修飾符 *}<{$content|truncate:200:'...'}>
{* 轉義輸出 *}<{$userInput|escape:'html'}>{* 條件 *}<{if $isAdmin}> <a href="admin.php">管理員</a><{elseif $isUser}> <a href="profile.php">配置文件</a><{else}> <a href="login.php">登錄</a><{/if}>
{* 循環 *}<{foreach item=item from=$items name=itemloop}> <{$smarty.foreach.itemloop.index}>: <{$item.title}><{/foreach}>{* 包含另一個模板 *}<{include file="db:mymodule_header.tpl"}>
{* 使用變量包含 *}<{include file="db:mymodule_item.tpl" item=$currentItem}>
{* 從主題包含 *}<{include file="file:$theme_path/partials/sidebar.tpl"}>- 設計師友好:HTML 類語法
- 緩存:內置模板緩存
- 安全:PHP 代碼隔離
- 靈活性:修飾符、函數、插件
- 自定義:用戶可以修改模板
- 社區:大型 Smarty 生態系統
- 學習曲線:Smarty 特定語法
- 開銷:需要編譯步驟
- 調試:模板錯誤可能不清楚
- 版本問題:版本之間的變更
- 學習:全面文檔
- 性能:積極緩存
- 調試:調試控制台、清晰的錯誤信息
- 版本:XOOPS 中的兼容層
timeline title XOOPS 中的 Smarty 2003 : Smarty 2.x : 初始集成 2013 : Smarty 3.0 : XOOPS 2.5.5 2020 : Smarty 3.1 : XOOPS 2.5.10 2026 : Smarty 4/5 : XOOPS 4.0遷移:Smarty 3 到 4/5
Section titled “遷移:Smarty 3 到 4/5”{* Smarty 3 - 已棄用 *}<{php}>echo date('Y');<{/php}>
{* Smarty 4+ - 使用修飾符或從 PHP 分配 *}<{$current_year}>
{* Smarty 3 - {section} 已棄用 *}<{section name=i loop=$items}> <{$items[i].title}><{/section}>
{* Smarty 4+ - 使用 {foreach} *}<{foreach $items as $item}> <{$item.title}><{/foreach}>XOOPS 提供了一個兼容層以順利過渡:
// XoopsTpl 使用兼容性方法擴展 Smartyclass XoopsTpl extends Smarty{ public function assign($tpl_var, $value = null) { // 處理 Smarty 3 和 4 語法 return parent::assign($tpl_var, $value); }}考慮的替代方案
Section titled “考慮的替代方案”1. Twig
Section titled “1. Twig”優點:現代、Symfony 生態系統 缺點:不同語法、遷移工作 決策:XOOPS 3.x 的可能未來選項
2. Blade (Laravel)
Section titled “2. Blade (Laravel)”優點:清潔語法、流行 缺點:Laravel 特定 決策:不適合獨立使用
3. 本地 PHP 模板
Section titled “3. 本地 PHP 模板”優點:無學習曲線、快速 缺點:安全風險、無分離 決策:因可維護性被拒絕
- ADR-001:模塊化架構
- ADR-002:數據庫抽象
- Smarty 文檔:https://www.smarty.net/docs/en/
- XOOPS 模板系統指南
- Web 應用中的 MVC 模式
#xoops #architecture #adr #smarty #templates #design-decision