帝国CMS灵动标签排序错误,常因附表字段未LEFT JOIN、varchar按字符串排序或自定义模型字段未建索引,排查应依次确认字段归属、SQL JOIN、排序字段类型与搜索索引。
帝国CMS灵动标签排序错误通常不是 order by 本身拼错,而是排序列落在附表、字段类型是 varchar、或者查询没有 JOIN 附表导致字段为空但前台又能显示主表,遇到“排序看起来乱了”“自定义模型创建后前台不显示”“全站搜索不到自定义字段”时,建议按下面顺序排查:字段归属主表/附表 → SQL 是否 JOIN → 排序字段类型 → 搜索索引。
问题场景:排序看似写了,前台顺序却不对
例如你在产品模型里加了自定义字段 price,后台录入方便就直接用文本字段,灵动标签里写:
帝国CMS灵动标签排序错误,SQL排序、附表字段与自定义模型不显示的完整排查
[e:loop={"select id,title,titleurl,price from phome_ecms_product where checked=1 order by price desc limit 10",10,24,0}]
<li><a href="<?=$bqsr['titleurl']?>"><?=$bqr['title']?></a> ¥<?=$bqr['price']?></li>
[/e:loop]
前台可能出现:
999 899 10000 1000
这不是帝国CMS的标签失灵,而是 price 字段是 varchar,MySQL 按字符串排序,修复方式要么在模型里把字段改成 int 或 decimal,要么在 SQL 里强制转换:
ORDER BY CAST(price AS UNSIGNED) DESC, id DESC
如果字段在附表,还要先解决 JOIN,否则连值都取不到。
自定义模型创建后前台不显示排查
帝国CMS 自定义模型通常会生成主表 phome_ecms_模型名 和附表 phome_ecms_模型名_data_1,主表一般存 id、title、titleurl、newstime、classid、checked 等系统字段,正文和大部分自定义字段默认落在附表。
自定义模型前台不显示,按下面顺序查:
- 栏目是否绑定了该自定义模型。
- 信息是否审核通过,
checked=1。 - 字段是否启用,是否实际在附表里。
- 模板里是否把附表字段直接当主表字段调用,页是否重新生成,列表页是否使用正确的
classid或 SQL。
典型错误 SQL,只查主表:
select id,title,zidingyi from phome_ecms_article where checked=1 order by id desc limit 10
zidingyi 在附表,这样不是排序错误,而是 zidingyi 直接不显示或报错,正确写法:
select a.id,a.title,a.titleurl,b.zidingyi from phome_ecms_article a left join phome_ecms_article_data_1 b on a.id=b.id where a.checked=1 order by b.zidingyi desc,a.id desc limit 10
灵动标签中的完整写法:
[e:loop={"select a.id,a.title,a.titleurl,b.zidingyi from phome_ecms_article a left join phome_ecms_article_data_1 b on a.id=b.id where a.checked=1 order by b.zidingyi desc,a.id desc limit 10",10,24,0}]
<li><a href="<?=$bqsr['titleurl']?>"><?=$bqr['title']?></a> <?=$bqr['zidingyi']?></li>
[/e:loop]
灵动标签 SQL 调用怎么写
灵动标签 SQL 调用格式为:
[e:loop={"SQL语句",显示条数,操作类型,只显示有标题图片}][/e:loop]
循环体内使用 $bqr['字段名'] 获取 SQL 查询出来的字段,使用 $bqsr 获取系统字段,$bqsr['titleurl']。
示例:调用新闻最新 10 条,按时间倒序,同时间按 ID 倒序:
[e:loop={"select id,title,titleurl,newstime from phome_ecms_news where checked=1 order by newstime desc,id desc limit 10",10,24,0}]
<li>
<a href="<?=$bqsr['titleurl']?>"><?=htmlspecialchars($bqr['title'])?></a>
<span><?=date('Y-m-d H:i',$bqr['newstime'])?></span>
</li>
[/e:loop]
这里有几个习惯建议:
- SQL 里写
limit时,尽量和灵动标签第二参数“显示条数”保持一致,避免分页或截断行为不一致。 - 表前缀示例用
phome_,如果安装时改过前缀,需要替换。 - 排序字段如果可能为空,先处理空值,避免空值排到最前:
ORDER BY (b.px IS NULL OR b.px='') ASC, CAST(b.px AS UNSIGNED) DESC, a.newstime DESC
- 字符串数字字段临时排序:
ORDER BY CAST(b.price AS DECIMAL(10,2)) DESC
列表模板和内容模板变量调用方法
列表模板的循环体通常使用帝国CMS内置列表变量:
[!--empirenews.listtemp--] <li> <a href="[!--titleurl--]">[!--title--]</a> <span>[!--newstime--]</span> </li> [!--/empirenews.listtemp--]
列表模板里可以直接调用主表字段,如 [!--title--]、[!--titleurl--]、[!--newstime--]、[!--classname--],但附表字段不能直接通过 [!--zidingyi--] 输出,这是很多人改模板时的坑。
模板中调用字段:
<h1>[!--title--]</h1> <div>来源:[!--befrom--]</div> <div>作者:[!--writer--]</div> <div class="content">[!--newstext--]</div> <div>自定义字段:[!--zidingyi--]</div>
模板中副表字段可以正常输出,如果内容页也不显示,去模型字段管理里检查该字段是否启用、是否属于该内容模板使用,以及是否重新生成了内容页。
万能标签和智能标签区别和使用场景
帝国CMS里常用的 [ecmsinfo] 一般称为万能标签,[e:loop] 通常叫灵动标签,也常被归为智能标签/灵活调用标签。
万能标签 [ecmsinfo]
语法:
[ecmsinfo]栏目ID,显示条数,标题截取长度,是否显示时间,操作类型,模板ID,只显示有标题图片[/ecmsinfo]
示例:
[ecmsinfo]1,10,30,0,0,1,0[/ecmsinfo]
优点是调用简单、可复用模板、适合栏目标准列表和固定排序,缺点是排序条件受后台模型默认字段限制,不太适合按附表字段或复杂条件排序。
智能标签/灵动标签 [e:loop]
适合复杂 SQL、跨表 JOIN、自定义字段排序、多模型聚合、空值控制等场景,排序错误大多出现在这个标签里,因为应用场景复杂,SQL 写错的风险也更高。
简单对比:
| 类型 | 语法 | 排序控制 | 适用场景 |
|---|---|---|---|
| 万能标签 | [ecmsinfo] |
内置为主 | 标准栏目列表、分页列表 |
| 灵动标签 | [e:loop] |
SQL 任意 | 首页聚合、附表字段排序、跨模型查询 |
全站搜索配置和自定义字段索引
自定义字段在后台录入正常,但全站搜索搜不到,通常不是模板问题,而是搜索配置里没有给该字段建立索引。
排查步骤:
- 进入后台「系统设置」→「搜索设置」。
- 找到对应数据模型,添加需要参与搜索的字段,包括主表和附表字段。
- 保存后更新全部搜索索引或重建索引。
- 前台搜索表单里的
show参数必须包含该字段名。
搜索表单示例:
<form action="/e/search/index.php" method="get"> <input type="text" name="keyboard" placeholder="输入关键词"> <input type="hidden" name="show" value="title,smalltext,newstext,zidingyi"> <input type="hidden" name="classid" value="0"> <button type="submit">搜索</button> </form>
注意:show 参数中多个字段用英文逗号分隔,不要加空格,如果自定义字段在附表,只写前台 show 参数不会生效,后台搜索设置必须同时勾选该字段并完成索引更新。
模板中调用附表字段的实现技巧
附表字段的调用核心就是:主表 LEFT JOIN 附表,以产品模型为例:
[e:loop={"select a.id,a.title,a.titleurl,b.price,b.stock from phome_ecms_product a left join phome_ecms_product_data_1 b on a.id=b.id where a.checked=1 and b.price!='' order by (b.price is null or b.price='') asc,cast(b.price as unsigned) desc limit 12",12,24,0}]
<div class="product">
<a href="<?=$bqsr['titleurl']?>"><?=htmlspecialchars($bqr['title'])?></a>
<span>¥<?=htmlspecialchars($bqr['price'])?></span>
<span>库存:<?=htmlspecialchars($bqr['stock'])?></span>
</div>
[/e:loop]
实现技巧:
- 表别名必须清晰,排序字段带别名,避免字段歧义。
- 附表字段参与排序前,先处理空值,避免空字符串排到最前。
- 纯数字字段如果已经是
varchar,优先使用CAST(字段 AS UNSIGNED)或CAST(字段 AS DECIMAL(10,2))排序。 - 如果该字段频繁用于排序、筛选、搜索,将字段从附表移到主表会明显减少 JOIN 和排序成本,页直接调用附表字段用
[!--字段名--],列表页、首页调用附表字段建议走灵动标签 SQL。 - 如果每页都按附表字段排序,后台给该字段加索引,否则数据量上来后排序会变慢。
修复清单
遇到帝国CMS灵动标签排序错误,不要只盯着 order by,按这条链路走:
- 确认排序列在主表还是附表。
- 附表字段是否已经
LEFT JOIN。 - 字段类型是否为数值/时间戳,而不是
varchar。 - SQL 中空值是否影响排序。
- 前台不显示时检查
checked=1、栏目绑定、字段启用。 - 全站搜索不到时检查搜索设置和自定义字段索引。
- 列表页调附表字段用灵动标签 SQL,内容页用
[!--字段名--]。 - 高频排序字段建议改类型、加索引或移到主表。


