Products
96SEO 2025-09-16 11:35 1
织梦作为国内非常流行的内容管理系统,因其灵活的栏目和文档管理功能被广泛应用于企业网站和资讯门户建设中。只是 在实际开发过程中,许多站长会遇到一个棘手的问题:使用{dede:arclist}
标签调用副栏目下的文章时列表却不显示这些文章。
这一问题尤其明显在一篇文章被多个副栏目关联时。主栏目调用正常,但切换到副栏目页面或直接用arclist标签调用对应副栏目的文章时却无法正确显示。
{dede:arclist}
标签中指定typeid为副栏目的ID,却调不到该副栏目的文章。织梦系统中,一篇文档有主栏目ID和多个交叉栏目标识。默认情况下 arclist标签,只从主栏目的子孙ID集合中筛选文章,没有针对交叉栏目的兼容判断。这导致当传入的是某个交叉栏目的ID时 由于未包含在GetSonIds函数返回集内,查询条件排除这些文档,从而出现不显示现象。
/include/taglib/arclist.lib.php文件负责生成arclist标签底层SQL查询语句。该文件295-296行左右存在关键代码:
if {
$orwheres = ' IN .')';
} else {
$orwheres = ' IN .','.$CrossID.')';
}
此处$CrossID变量默认只支持一个交叉目录,不支持多目录组合。如果文档设置了多个交叉目录,则无法通过此处逻辑正确匹配全部相关栏目,从而导致查询后来啊遗漏。
有些站长为筛选带特定flag标记的文档,在arclist标签加入flag参数。但由于原始代码中flag与crossid联合过滤逻辑存在漏洞,导致带flag属性时反而无法调出交叉栏目的文档。
- 修改/include/taglib/arclist.lib.php文件, 将上面提及代码改成支持一个$CrossID,比如加上if判断强制添加CrossId。但只能解决单个交叉目录的问题,不支持多目录场景;且升级后易被覆盖,需要重复修改维护。
- {dede:list}标签对交叉栏目支持较好,可以直接调用多个交叉目录下的内容。但其模板灵活性、 缓存机制及分页能力相较arclist存在劣势,有些业务需求难以满足,所以呢不是万能方案。
- 直接修改数据库查询语句,将主栏目和所有选择的跨栏目信息用SQL UNION或LIKE模糊匹配进行 。这种方法灵活,但需要掌握SQL编写,并且增加了程序复杂度和维护难度,不推荐初学者尝试。
下面提供一个基于官方最新版本5.7 SP1基础上的原创修正办法, 实现arclist标签精准、稳定地调用包含多个副栏目的文章列表!
/include/taglib/arclist.lib.php
// 原代码示范:
if {
$orwheres = ' IN . ')';
} else {
$orwheres = ' IN . ',' . $CrossID . ')';
}
// 修改为:
// 如果$CrossIDs是字符串逗号分隔形式, 需要拆分成数组
if ) {
// 支持逗号分割多个crossid转成数组
if ) {
$arr_crossids = explode);
} elseif ) {
$arr_crossids = $CrossIDs;
} else {
$arr_crossids = array;
}
// 获取当前$typeid所有子孙节点
$sonids_str = GetSonIds;
// 合并所有crossids 和 主类型
foreach {
$v = intval);
if {
// 防止注入一边保证格式正确
// 将各cross id追加进过滤条件字符串
if $v) === false) {
$sonids_str .= ',' . $v;
}
}
}
// 到头来生成包含主+所有跨目录集合字符串条件
if {
$orwheres = " IN . ")";
} else {
// 万一空白则只用$typeid本身
$orwheres = " IN . ")";
}
} else {
// 无跨目录直接正常处理
if {
$orwheres = " IN ) . ")";
}
}
确保flag筛选条件和跨栏目信息一边生效,不产生冲突:
// 示例伪代码
// 查询where条件拼接部分:
$whereArr = array;
// 栏目范围条件已处理,如上所示
// 添加flag判断:
if){
// 确保flag字段平安有效再拼接sql:
$whereArr = " FIND_IN_SET)."', flag)";
}
// 到头来拼接完整sql where语句:
$whereSql= implode;
// 在到头来sql语句里添加$whereSql即可保证两边兼顾。
背景:
问 题 描 述 | 专业解答指导 |
---|---|
为什么使用{dede:arclist typeid=XX} 调用时看不到选择为该类型的所有附属专? |
主要是主要原因是底层SQL没有将跨模块综合起来做IN判断, 需要按照上述示例做 才能完全覆盖,否则只能调取主类型下数据。
请结合/include/taglib/arclist.lib.php 文件中getSqlWhere函数段落查找关键位置进行调整即可。
如果想临时绕过 可以考虑利用{dede:list} 标签代替,它天生支持按附属专来读取,不过分页样式需要自己DIY控制。
为保证长期稳定运行,请优先建议做好源码级别补丁合并。
这通常是主要原因是原版 arclib 中对 flag 字段过滤写法存在冲突或者未平安转义的问题,
建议参考本文第三步所示增加严格检测和平安转义措施,再结合where条件统一拼装方式同步优化。
有可能影响,主要原因是官方更新会覆盖include/taglib/arclist.lib.php 文件。
最佳实践是保留备份差异patch, 根据每次升级版本核对变动,自行合并差异修复;
也可考虑开发插件形式替代核心文件硬改,但技术门槛较高。
简单来说:
Demand feedback