核心规则:嵌套标签的语法
在 DedeCMS 中,嵌套标签必须使用 特定属性 来实现,而不能像普通 HTML 标签那样直接嵌套。

主要属性:innertext 和 reid
这是实现嵌套最常用、最核心的方法。
-
innertext:这个属性用于获取父级标签内部的全部内容,在子标签循环时,[field:innertext/]会输出父标签当前循环项的完整 HTML 结构。 -
reid:这个属性用于指定子标签应该从哪个父级标签的字段中获取其查询的 ID 或条件,它解决了子标签不知道自己属于哪个父级数据的问题。
基本语法结构:

<!-- 父级标签 -->
{dede:parenttagname}
<!-- 子级标签 -->
{dede:childtagname reid='[field:id/]'}
<!-- 在这里使用 [field:innertext/] 来输出父级的整个块 -->
[field:innertext/]
{/dede:childtagname}
{/dede:parenttagname}
工作原理:
- 父级标签(如
{dede:arclist})开始循环。 - 对于父级的每一个数据项(比如一篇文章),DedeCMS 会解析其内部的
{dede:childtagname}。 reid='[field:id/]'告诉子标签:“你的查询条件(aid)应该等于当前父级循环项的id值”。- 子标签执行查询,获取与当前父级 ID 相关的数据。
[field:innertext/]会输出父级标签从开始到结束之间的所有内容,包括 HTML 标签和子标签自身,形成一个完整的循环块。
实战示例
示例 1:文章列表内嵌套该文章的评论列表(最经典的应用)
这是一个非常典型的场景:显示文章列表,并且在每篇文章下面显示这篇文章的评论。
模板代码 (article_list.htm):
{dede:arclist row='5' titlelen='30'}
<article class="post-item">
<h2><a href="[field:arcurl/]">[field:title/]</a></h2>
<p class="summary">[field:description function='cn_substr(@me, 100)'/]...</p>
<!--
这里开始嵌套评论列表
1. 使用 {dede:feedback} 作为子标签
2. 使用 reid='[field:id/]' 将子标签的查询与当前文章的 ID 绑定
3. 在 feedback 标签内部使用 [field:innertext/] 来包含整个评论块
-->
{dede:feedback reid='[field:id/]' row='3'}
[field:innertext/]
{/dede:feedback}
<!-- 如果没有评论,可以显示一个默认提示 -->
{dede:feedback reid='[field:id/]' row='0' noset='yes'}
<div class="comment-section">
<p>暂无评论,快来抢沙发吧!</p>
</div>
{/dede:feedback}
</article>
{/dede:arclist}
CSS 样式 (为了更清晰):

.post-item {
border: 1px solid #eee;
padding: 15px;
margin-bottom: 20px;
border-radius: 5px;
}
.comment-section {
margin-top: 15px;
padding-top: 15px;
border-top: 1px dashed #ccc;
}
.comment-item {
background-color: #f9f9f9;
padding: 10px;
margin-bottom: 10px;
border-radius: 3px;
}
.comment-author {
font-weight: bold;
color: #0066cc;
}
.comment-content {
margin-top: 5px;
}
效果解释:
{dede:arclist} 会循环输出 5 篇文章,对于每一篇文章,{dede:feedback reid='[field:id/]'} 都会执行一次,查询 arcticleid 等于当前文章 id 的评论。[field:innertext/] 会包含下面定义的评论 HTML 结构,从而将评论正确地渲染在对应的文章下方。
示例 2:栏目列表内嵌套该栏目的子栏目
假设你想显示一个父栏目列表,并在每个父栏目后面列出它的所有子栏目。
模板代码:
{dede:channelartlist typeid='top' row='3'}
<div class="parent-channel">
<h3><a href="[field:typeurl/]">[field:typename/]</a></h3>
<!--
嵌套子栏目列表
使用 {dede:channel} 作为子标签
使用 reid='[field:id/]' 将子标签的查询与当前父栏目的 ID 绑定
-->
{dede:channel reid='[field:id/]'}
<ul class="sub-channel-list">
<li><a href="[field:typeurl/]">[field:typename/]</a></li>
</ul>
{/dede:channel}
</div>
{/dede:channelartlist}
效果解释:
{dede:channelartlist} 循环顶级栏目,对于每一个父栏目,{dede:channel reid='[field:id/]'} 会查询出 reid(父栏目ID)等于当前父栏目 id 的所有子栏目,并以 <ul> 列表的形式输出。
重要注意事项
-
并非所有标签都支持嵌套:只有 DedeCMS 内置的支持
innertext和reid属性的标签才能作为子标签被嵌套。{dede:arclist},{dede:channelartlist},{dede:feedback},{dede:myad}等都支持,而像{dede:field}、{dede:global}、{dede:php}等通常是输出单一值的标签,不能作为父级标签来嵌套其他循环标签。 -
性能影响:嵌套标签会增加数据库查询次数,上面的文章列表嵌套评论的例子,如果文章列表有 10 篇,并且每篇文章平均有 3 条评论,那么总共会执行 1(查询文章) + 10 * 3(查询评论) = 31 次数据库查询,如果数据量很大,可能会导致页面加载缓慢,请谨慎使用。
-
标签闭合:嵌套的标签必须正确地用
{/dede:tagname}闭合,否则会导致解析错误。 -
字段命名:确保
reid属性中引用的字段(通常是id)是父级标签循环项中确实存在的字段,并且子标签能够识别这个reid参数(feedback标签会自动将其作为arcticleid来查询)。
在 DedeCMS 标签内使用标签,核心就是 reid 和 innertext 的组合。
reid:建立父子关系,告诉子标签“你是属于谁的”。innertext:构建循环块,告诉子标签“你应该把整个父级结构包含进去”。
掌握了这个技巧,你就可以构建出非常复杂和动态的页面结构,如文章带评论、栏目带子栏目、产品带规格等,但始终要牢记其对性能的影响,避免在循环过深的场景下滥用。
