主题数据装配 Portal
inc/..from_theme.php 是主题级的数据装配脚本,让主题自己能按当前路由决定往模板里塞哪些数据(而不必改控制器代码)。脚本内一律用 Portal:: 静态门面取值 / 赋值。
一、加载时机
由 ThemeExtensionLoader 在路由(module / action)已确定、控制器执行之前加载:
- 文件不存在则跳过(可选文件,
default主题就没有); - 加载前引擎会
Portal::boot()写入当前路由与赋值目标; - 每个请求只加载一次(
include_once)。
二、示例
<?php
use Dou\Core\Facade\Portal;
if (Portal::routeModule() === 'index') {
Portal::assign('product_category', Portal::categoryTree('product'));
Portal::assign('recommend_case', Portal::columnList('cases', 'ALL', 4, 'sort ASC'));
}
Portal::assign('left_article', Portal::columnList('article', 'ALL', 5, 'sort ASC'));
要点:Portal::routeModule() 判断当前路由模块(index 为首页),首页专属的大列表只在首页装配;Portal::assign() 把结果赋给模板变量,模板中用 {$left_article} 访问。
三、Portal 常用 API
| 方法 | 用途 |
|---|---|
assign($key, $value) |
赋值模板变量 |
routeModule() / routeAction() |
当前路由模块名 / 动作名(首页固定为 index) |
langKey($key, $default = '') |
取语言项 |
columnList($module, $catId = 'ALL', $limit = 0, $sort = '', $extraScopes = array(), $excerptLength = 200) |
栏目模块内容列表(catId 传 'ALL' 不按分类过滤;limit 传 0 不限制;sort 形如 'sort ASC';description 默认截 200 字) |
singleList($module, $limit = 0, $sort = '', $excerptLength = 200) |
简单(无分类)模块内容列表 |
categoryTree($module, $currentCatId = 0) |
分类嵌套树($currentCatId 匹配的节点带 cur 标记) |
categoryTreeWithItems($module, $itemNumber = 5, $includeChildren = false, $excerptLength = 200) |
分类树 + 每类内容(节点:category_id / name / list / child) |
showList($type = 'pc') |
幻灯 / 横幅列表 |
boxList($classSlug = '') |
指定装饰位(box)列表 |
data($code = null, $field = null, $default = null) |
主题 data 字典(data() 取整表、data('hero') 取单行、data('hero', 'image') 取单字段) |
linkList() |
友情链接列表 |
page($uniqueId) / pageTree($parentId = 0, $currentId = '') |
单页行 / 单页嵌套树 |
listFor($module, $props) / categoryFor($module, $props) |
{list} / {category} 模板标签的取数后端(同请求内按 module + props 缓存) |
categorySubtreeIds($module, $catId) |
分类自身 + 全部子孙的分类 ID 集合 |
行为约定:列表类方法只对已安装/已启用(features 开启)且命中 Model 的模块生效;模块未装或不可列表时返回空数组,不会报错。
四、安全白名单(重要)
加载前会做一次 SQL 关键字检查:文件内容(不区分大小写,含注释与字符串)出现下列任一英文词,整个脚本会被跳过、不执行:
insert / update / delete / create / truncate / drop / alter / into / load_file / outfile
因此脚本里的变量名、注释、文案都不要使用这些英文词(例如别写 $update_list,可改名 $new_list)。
五、与模板取数标签的分工
- 需要「跟着路由走的装配逻辑」或复杂的自定义结构 → 用
inc/..from_theme.php; - 只是模板里想直接循环一段内容 → 优先用
{list}/{category}标签,无需写脚本。
两者取数走的是同一套后端(Portal),可混用。