dede三级栏目循环如何实现?

99ANYc3cd6
预计阅读时长 17 分钟
位置: 首页 DEDE建站 正文

下面我将为您提供最常用、最清晰的两种实现方法:传统嵌套法递归模板法,递归法在处理无限层级时更为优雅和强大。

dede 三级栏目循环
(图片来源网络,侵删)

准备工作:栏目结构

请确保您的后台栏目结构是清晰的,一个典型的三级栏目结构如下:

  • 一级栏目 (ID: 1): 公司简介
    • 二级栏目 (ID: 2): 发展历程
      • 三级栏目 (ID: 3): 2025年
      • 三级栏目 (ID: 4): 2025年
    • 二级栏目 (ID: 5): 企业文化
      • 三级栏目 (ID: 6): 使命愿景
      • 三级栏目 (ID: 7): 核心价值观
  • 一级栏目 (ID: 8): 产品中心
    • 二级栏目 (ID: 9): 软件产品
      • 三级栏目 (ID: 10): ERP系统
      • 三级栏目 (ID: 11): CRM系统
    • 二级栏目 (ID: 12): 硬件产品
      • 三级栏目 (ID: 13): 服务器
      • 三级栏目 (ID: 14): 存储设备

我们将基于这个结构来编写代码。


传统嵌套法(适用于固定层级)

这种方法最直观,适合明确知道只需要三级栏目结构的情况,代码直接写在模板文件里。

适用场景:栏目层级固定,结构不会轻易变化。

代码示例

<ul class="top-nav">
    <!-- 循环一级栏目 -->
    {dede:channel type='top' row='8'}
    <li>
        <a href="[field:typelink/]">[field:typename/]</a>
        <!-- 循环当前一级栏目下的二级栏目 -->
        {dede:channel type='son' typeid='[field:id]' row='10'}
        <ul class="sub-nav">
            <li>
                <a href="[field:typelink/]">[field:typename/]</a>
                <!-- 循环当前二级栏目下的三级栏目 -->
                {dede:channel type='son' typeid='[field:id]' row='10'}
                <ul class="third-nav">
                    <li><a href="[field:typelink/]">[field:typename/]</a></li>
                </ul>
                {/dede:channel}
            </li>
        </ul>
        {/dede:channel}
    </li>
    {/dede:channel}
</ul>

代码解析

  1. {dede:channel type='top' row='8'}:

    • type='top': 获取所有顶级栏目(一级栏目)。
    • row='8': 限制显示8个一级栏目。
    • 循环输出所有一级栏目。
  2. {dede:channel type='son' typeid='[field:id]' row='10'}:

    • type='son': 获取指定 typeid 的子栏目。
    • typeid='[field:id]': 这是关键!这里的 [field:id] 是外层循环(一级栏目)的栏目ID,这句代码的意思是“获取当前这个一级栏目下的所有二级栏目”。
    • 嵌套在一级栏目循环内部,循环输出所有二级栏目。
  3. 最内层 {dede:channel}:

    • 同样使用 type='son'typeid='[field:id]'
    • 这里的 [field:id] 是中间层循环(二级栏目)的栏目ID,这句代码的意思是“获取当前这个二级栏目下的所有三级栏目”。
    • 嵌套在二级栏目循环内部,循环输出所有三级栏目。

递归模板法(推荐,适用于无限层级)

递归方法更灵活,可以轻松应对四、五级甚至更多层级的栏目,并且代码结构更清晰,易于维护,它通过一个单独的模板文件来循环子栏目,然后自身调用自己。

适用场景:栏目层级不确定或可能动态增加,希望代码更具扩展性。

实现步骤

第1步:创建子栏目循环模板文件

在您的模板目录(通常是 /templets/default/)下,新建一个文件,subnav.htm。 (subnav.htm)**:

<ul class="sub-level">
    <!-- 循环当前层级的所有子栏目 -->
    {dede:channel type='son' typeid='[field:global name=typeid/]' row='20'}
    <li>
        <a href="[field:typelink/]">[field:typename/]</a>
        <!-- 递归调用:如果当前栏目还有子栏目,则再次调用本模板 -->
        {dede:if condition="(@me['soncount'] > 0)"}
            {dede:include filename="subnav.htm" typeid="[field:id]"/}
        {/dede:if}
    </li>
    {/dede:channel}
</ul>

代码解析

  1. {dede:channel type='son' typeid='[field:global name=typeid/]' row='20'}:

    • typeid='[field:global name=typeid/]': 这里我们使用全局变量 typeid 来传递父级栏目的ID,这个变量会在调用模板时被指定。
    • 这句代码会获取传递进来的 typeid 对应的所有子栏目。
  2. {dede:if condition="(@me['soncount'] > 0)"}:

    • 这是一个条件判断。@me['soncount'] 是当前栏目的子栏目数量。
    • soncount 大于 0,说明当前栏目还有下级栏目,就执行递归调用。
  3. {dede:include filename="subnav.htm" typeid="[field:id]"/}:

    • 这是递归的核心,它包含 subnav.htm 文件本身。
    • typeid="[field:id]": 这是关键!它将当前循环到的栏目的ID作为新的 typeid 传递给下一次的 subnav.htm 调用,这样,下一次循环就会查找这个新ID的子栏目,形成递归。

第2步:在主模板中调用递归

在你的主栏目模板文件(head.htmnav.htm)中,你可以这样调用它来生成任意层级的导航。

主模板调用示例

<ul class="main-nav">
    <!-- 循环一级栏目 -->
    {dede:channel type='top' row='8'}
    <li>
        <a href="[field:typelink/]">[field:typename/]</a>
        <!-- 调用递归模板,传入一级栏目的ID -->
        {dede:include filename="subnav.htm" typeid="[field:id]"/}
    </li>
    {/dede:channel}
</ul>

流程说明

  1. 主模板循环一级栏目。
  2. 当循环到某个一级栏目(公司简介”,ID=1)时,执行 {dede:include filename="subnav.htm" typeid="1"}
  3. subnav.htm 被调用,typeid 为 1,它查找 ID=1 的所有子栏目(即“发展历程”和“企业文化”)。
  4. 循环到“发展历程”(ID=2)时,因为它的 soncount > 0,所以它会再次调用 subnav.htm,但这次传入的 typeid 是 2。
  5. 新的 subnav.htm 调用查找 ID=2 的所有子栏目(即“2025年”和“2025年”)。
  6. 因为“2025年”和“2025年”没有子栏目(soncount=0),所以不再递归调用。
  7. 这个过程会一直持续,直到所有层级的栏目都被遍历完毕。

总结与对比

特性 传统嵌套法 递归模板法
代码结构 所有层级写在一个文件里,代码冗长。 结构清晰,主模板和子模板分离。
扩展性 差,增加第四级需要再嵌套一层,代码会变得很乱。 极佳,可以轻松处理无限层级,无需修改代码。
维护性 差,修改样式或逻辑需要在一大段嵌套代码中寻找。 ,修改子栏目的样式或逻辑只需编辑 subnav.htm
适用场景 栏目层级固定且较少(如最多三级)。 栏目结构复杂、层级不确定,或需要长期维护的项目。

强烈推荐使用方法二(递归模板法),它代表了 DedeCMS 模板开发中更专业、更灵活的实践方式,能让你未来的维护工作事半功倍。

-- 展开阅读全文 --
头像
strncpy函数为何要手动补\0?
« 上一篇 03-06
织梦当前文章Id标签如何获取?
下一篇 » 03-06

相关文章

取消
微信二维码
支付宝二维码

目录[+]