Yii2 的 yii\base\Theme 類別提供強大的視圖檔案路徑映射機制,支援多主題切換、主題繼承、資源路徑管理。本文詳細解析配置策略、核心屬性、替換演算法與繼承模式實戰。
'components' => [
'view' => [
'theme' => [
'pathMap' => [
'@app/views' => '@app/themes/basic',
],
'baseUrl' => '@web/themes/basic',
],
],
],
主題本質是 字串映射替換 + 檔案存在性驗證:
$pathMap = [
'@app/a' => '@app/aaa',
'@app/b' => '@app/bbb',
];
// @app/a/site/index.php → @app/aaa/site/index.php (若存在)
$pathMap = [
'@app/c' => [
'@app/ccc/xxx',
'@app/ccc/yyy',
],
];
// @app/c/site/index.php 依序嘗試:
// 1. @app/ccc/xxx/site/index.php (存在則返回)
// 2. @app/ccc/yyy/site/index.php (存在則返回)
// 3. 全部不存在 → 返回原路徑 @app/c/site/index.php
場景:預設主題 default,新增暗色主題 dark 僅覆寫版型檔案。
$pathMap = [
'@app/views' => [
'@app/themes/dark', // 優先查找 dark 主題
'@app/themes/default', // 找不到回退到 default
],
];
優勢:dark 僅需包含差異檔案,自動繼承 default 的其餘視圖,維護成本極低。
| 屬性 | 說明 | 範例 |
|---|---|---|
pathMap | 路徑映射規則陣列,支援多目標繼承 | ['@app/views' => ['@app/themes/dark', '@app/themes/default']] |
baseUrl | 主題資源(CSS/JS/圖片)公開 URL 基礎路徑,不含尾斜線 | @web/themes/dark |
basePath | 主題資源實體檔案目錄 | @app/themes/dark |
public function init() {
parent::init();
if (empty($this->pathMap)) {
if (($basePath = $this->getBasePath()) === null) {
throw new InvalidConfigException('The "basePath" property must be set.');
}
// 回退相容模式:當前模組基礎路徑映射到 basePath
$this->pathMap = [Yii::$app->getBasePath() => [$basePath]];
}
}
public function applyTo($path) {
$path = FileHelper::normalizePath($path);
foreach ($this->pathMap as $from => $tos) {
$from = FileHelper::normalizePath(Yii::getAlias($from)) . DIRECTORY_SEPARATOR;
if (strpos($path, $from) === 0) {
$n = strlen($from);
foreach ((array) $tos as $to) {
$to = FileHelper::normalizePath(Yii::getAlias($to)) . DIRECTORY_SEPARATOR;
$file = $to . substr($path, $n);
if (is_file($file)) return $file; // 找到即返回
}
}
}
return $path; // 全部不存在返回原路徑
}
'pathMap' => [
'@app/views' => ['@app/themes/dark', '@app/themes/default'],
'@app/modules' => '@app/themes/default/modules',
'@app/widgets' => '@app/themes/default/widgets',
],
// Controller 基類
public function beforeAction($action) {
$theme = Yii::$app->request->cookies->getValue('theme', 'default');
Yii::$app->view->theme->pathMap = [
'@app/views' => ["@app/themes/{$theme}", '@app/themes/default'],
];
return parent::beforeAction($action);
}
Yii2 主題系統以 pathMap 為核心,透過 有序多目標映射 + 檔案存在性驗證 實現靈活的主題繼承與回退機制。善用此特性可構建可維護、可擴充的多樣化介面架構。