模块列表 List
{list} 是 DouPHP 专属的内容列表标签:它按模块白名单自动从 Portal 取数,然后以与 {foreach} 相同的方式循环输出。无需在控制器里先查好数据再 assign,模板里一行就能拉出一段内容。
一、语法
{list module="模块名" item=值变量 [catId=分类ID] [limit=数量] [sort=排序] [excerpt=截字长度]
[key=键变量] [name=循环名称] [offset=跳过数]}
...
{listelse}
无数据时显示
{/list}
二、参数说明
| 参数 | 必需 | 说明 |
|---|---|---|
module |
是 | 模块名(必须为字面标识符,禁止运行时变量,防注入) |
item |
是 | 当前元素值变量名(字面标识符) |
catId |
否 | 分类 ID(仅栏目型模块);ALL / 空 = 不按分类过滤;其它值含子孙分类 |
limit |
否 | 取数条数(走 SQL LIMIT) |
sort |
否 | 排序,仅接受 字段名 ASC\|DESC 逗号序列,否则忽略走默认 id DESC |
excerpt |
否 | description 字段截字长度(默认 200,≤0 不截) |
key / name / offset |
否 | 同 {foreach};offset 在取数后切片 |
三、示例
{* 文章列表,取最新 10 条 *}
{list module="article" limit=10 item=article}
<li>{$article@iteration}. {$article.title|truncate:50}</li>
{listelse}
<li>暂无文章</li>
{/list}
{* 指定分类下产品,跳过前 5 条取 12 条 *}
{list module="product" catId=$cat_id limit=12 offset=5 item=product}
<div class="product">{$product.name}</div>
{/list}
四、数据源与白名单
{list} 编译为 \Dou\Core\Facade\Portal::listFor($module, $props) 调用,运行期由 Portal 按模块类型分流:
- 栏目型模块(在配置
module.column_module中声明)→ 走columnList,支持catId按分类过滤; - 简单模块(
module.single_module)→ 走singleList,无分类概念; - 模块未安装 / 未启用(
features关闭)或不可列表(未命中moduleSchema的 listable 白名单)→ 返回空数组,走{listelse}分支,不会报错。
module 在编译期就被固化为字面量,且必须是合法标识符,这保证了模板无法把请求参数注入模块名。
五、offset 与 limit 的区别
limit:进入 Portal 的 props,最终作用于 SQLLIMIT,在数据库层限制取数量;offset:编译期字面量,取数之后再做array_slice,与{foreach}的 offset 口径一致。
六、sort 白名单(防 ORDER BY 注入)
sort 只接受形如 字段名 ASC / 字段名 DESC 的逗号序列,任何不合法的排序串都会被忽略并回退到默认排序 id DESC。这是防止把用户输入拼进 ORDER BY 造成 SQL 注入的关键约束——切勿尝试把未经校验的动态串传给 sort。
七、请求级缓存
同一请求内,相同 module + props 的 {list} 块(以及等价的 Portal::listFor() 调用)共用一份缓存,重复块不重复查询。因此页面上多处相同条件的列表不会造成多次数据库访问。
八、循环层能力
{list} 与 {foreach} 共享循环层:item / key / name / offset 参数、@property 循环属性、{break} / {continue}、{listelse} 空态分支,用法完全一致。