自定义模型创建后前台不显示,字段索引去哪儿了?
你花了半小时建好了一个“产品库”自定义模型,添加了十几个字段,兴冲冲地跑到前台列表页,结果——空白,后台数据明明有记录,模板标签也没写错,问题出在哪?
排查路径: 先检查模型是否绑定了系统模型ID,再确认栏目是否关联了该模型,但更隐蔽的问题是:你给新字段建索引了吗? 帝国CMS的列表页默认只查询主表字段,自定义模型中的附表字段如果没有在phome_enewsshop(举例)的附加表里建立索引,列表页的WHERE条件就无法命中,导致数据读不出来。
帝国CMS二次开发实战,数据表字段索引添加与模板调用深度指南
解决方案: 进入后台“系统设置”→“数据表与字段”,找到你的模型附表,对需要作为查询条件的字段(如price、stock)执行:
ALTER TABLE `phome_enewsshop_data` ADD INDEX `idx_price` (`price`);
然后在列表模板中用灵动标签加条件:
[e:loop={"select * from phome_enewsshop where id in (select id from phome_enewsshop_data where price>100 and stock>0)",10,0}]
<li>[!--title--] - [!--price--]元</li>
[/e:loop]
注意:SQL里关联子查询的性能取决于索引,没索引就是全表扫描,必卡。
灵动标签SQL调用,附带字段怎么取?
你写了个灵动标签想调用自定义字段author,但[!--author--]死活不输出,因为灵动标签默认只查主表,需要用JOIN。
正确写法:
[e:loop={"select a.*, b.author, b.isbn from phome_ecms_article a left join phome_ecms_article_data b on a.id=b.id where a.classid=5 order by a.newstime desc limit 10",10,24,0}]
<li><a href="[!--titleurl--]">[!--title--]</a> - [!--author--]</li>
[/e:loop]
参数说明:第一个参数是SQL语句,第二个是显示条数,第三个是栏目ID(0为不限),第四个是操作类型(0为列表)。注意表前缀,别直接复制别人的。
列表模板和内容模板变量调用,区别在哪?
列表模板(list.var)循环输出时,每条记录相当于一个数组元素,变量用[!--字段名--]直接替换,但内容模板(show.var)是单条记录,字段通过$r[字段名]获取。
列表模板里调用附表字段:
[e:loop={"select * from phome_ecms_news inner join phome_ecms_news_data on phome_ecms_news.id=phome_ecms_news_data.id where phome_ecms_news.classid=3",8,3,0}]
<h2>[!--title--]</h2>
<p>价格:[!--price--] | 作者:[!--author--]</p>
[/e:loop]
```模板(showpage)里直接输出:**
```php
<?php
echo $r['price'] . '元';
echo $navinfo['title']; // 标题用系统变量
?>
```模板里`$r`是当前记录数组,包含所有主表和附表的字段,但前提是你在内容页模型绑定了附表。
## 场景四:万能标签 vs 智能标签,别搞混
- **万能标签(`ecmsvar`)**:本质是自定义SQL查询,返回数组,适合复杂逻辑,比如调用统计排行:
```html
[ecmsvar]select title from phome_ecms_news order by onclick desc limit 5[/ecmsvar]
使用时需要手动循环(用PHP或JS)。
- 智能标签(
e:loop):帝国封装的模板循环,参数固定,上手快,适合简单列表,但不支持子查询和复杂的JOIN,除非你写原生SQL放进去(如上例)。
选型建议: 涉及多表关联、统计、条件分组用万能标签+PHP代码块;纯展示列表用e:loop,维护容易。
全站搜索配置和自定义字段索引
默认搜索只匹配标题和正文,你要搜自定义字段model_no(型号)怎么办?
配置步骤:
- 后台“系统设置”→“全站搜索配置”,勾选你要搜索的模型。
- 附加表字段必须建立全文索引(MyISAM引擎)或普通索引(InnoDB)。
ALTER TABLE `phome_ecms_product_data` ADD FULLTEXT INDEX `ft_model` (`model_no`);
- 搜索模板(
search)里用条件:[e:loop={"select * from phome_ecms_product where id in (select id from phome_ecms_product_data where match(model_no) against ('%s' in boolean mode))",10,0}]注意:
%s会被帝国CMS自动替换为用户输入,但要防止SQL注入,建议用s_arg参数自动转义。
模板中调用附表字段的实现技巧
附表的字段默认不在主表查询结果里,最省事的方法是:修改模型的主表,把常用字段合并到主表(后台可以改字段归属表),但如果你不想动结构,用PHP拼接:
在列表模板顶部加:
<?php
$ids = array();
while($r = $empire->fetch($query)){ $ids[] = $r['id']; }
$ids_str = implode(',', $ids);
$data = $empire->query("select id, author, isbn from phome_ecms_article_data where id in ($ids_str)");
$map = array();
while($dr = $empire->fetch($data)){ $map[$dr['id']] = $dr; }
// 然后循环主记录时用 $map[$r['id']]['author'] 输出
?>
这样避免了对每条记录单独执行一次SQL查询,性能提升明显。在循环里不要查库,提前批量取出再映射。
最后提醒:索引不是越多越好
给字段加索引能提速,但插入和更新会变慢,实战中,只给WHERE、ORDER BY、JOIN条件里的字段加索引,比如classid、newstime、userid,以及你自定义的筛选字段,用EXPLAIN查看SQL执行计划,确认索引是否被命中。
就是帝国CMS二次开发中关于字段索引和模板调用的高频坑,下次遇到前台不显示,先查索引;遇到变量取不到,先查SQL连接方式;遇到搜索无结果,先查全文索引,按这套思路,省下半天排查时间。



发表评论