{dede:channel} 本身是一个循环输出栏目标签,但它不支持在标签内部直接使用类似 PHP 的 if...else... 语法,我们需要通过其他几种巧妙的方法来实现条件判断。

(图片来源网络,侵删)
我将为你介绍三种最常用和最有效的方法,从最推荐到备选方案排序。
使用 runphp 和 if 条件(最推荐、最灵活)
这是最强大、最灵活的方法,可以在模板中直接执行 PHP 代码并进行判断,它适用于绝大多数复杂的条件判断场景。
核心思路
利用 typeid、topid 等变量来判断当前栏目是否满足特定条件,然后通过 @me 变量来修改输出内容。
常用判断条件
- 顶级栏目判断:
$type['topid'] == '0' - 指定ID判断:
$type['id'] == $target_id - 当前栏目判断(高亮):
$type['id'] == $thisid - 栏目层级判断:
$type['sonids'](是否有子栏目)
示例代码
场景1:为顶级栏目和子栏目设置不同的样式

(图片来源网络,侵删)
{dede:channel type='top' row='8'}
<li>
<!--
判断逻辑:
1. 如果是顶级栏目 ($type['topid'] == 0),则输出 class="nav-main"
2. 否则,输出 class="nav-sub"
3. ' . ' 是 PHP 的字符串连接符
4. @me 是 runphp 修改前的原始值,这里我们用它来连接 class
-->
[field:typename function='str_replace("首页", "", "@me")'/]
<a href="[field:typelink/]" class="[field:typename runphp='yes']
$is_top = ($type['topid'] == 0) ? 'nav-main' : 'nav-sub';
@me = $is_top;
[/field:typename]">
[field:typename/]
</a>
</li>
{/dede:channel}
场景2:判断当前栏目并添加“active”或“current”高亮样式
这是最常见的应用,用于导航栏当前页面的高亮显示。
<ul class="nav">
{dede:channel type='top' row='8'}
<li>
<a href="[field:typelink/]"
class="nav-item [field:typename runphp='yes']
// 如果当前栏目的ID等于系统变量中的栏目ID,则添加 active 类
if($type['id'] == $thisid) @me = ' active';
// 否则,不添加任何类
else @me = '';
[/field:typename]">
[field:typename/]
</a>
</li>
{/dede:channel}
</ul>
更简洁的高亮写法(推荐):
<ul class="nav">
{dede:channel type='top' row='8'}
<li>
<a href="[field:typelink/]"
class="nav-item [field:typename runphp='yes']
// 三元运算符,更简洁
@me = ($type['id'] == $thisid) ? ' active' : '';
[/field:typename]">
[field:typename/]
</a>
</li>
{/dede:channel}
</ul>
使用 INSTR 字符串函数(适用于特定ID判断)
如果你的判断条件是“栏目ID是否在一个列表中”,这种方法比 runphp 更简洁。

(图片来源网络,侵删)
核心思路
使用 INSTR 函数检查一个字符串中是否包含另一个字符串,我们可以用它来检查当前栏目ID是否在你指定的ID列表中。
示例代码
场景:判断栏目ID是否为 1, 3, 5,如果是则添加特殊样式
{dede:channel type='top' row='8'}
<li>
<a href="[field:typelink/]"
class="nav-item [field:id function='str_replace(array("1", "3", "5"), "special-class", @me)'/]">
[field:typename/]
</a>
</li>
{/dede:channel}
代码解释:
[field:id]:获取当前栏目的ID。function='...':对获取到的ID值应用一个函数。str_replace(array("1", "3", "5"), "special-class", @me):array("1", "3", "5"):你想要匹配的ID列表。"special-class":如果匹配成功,替换成这个值(即添加的CSS类名)。@me:原始的栏目ID。- 这个函数的工作原理是:
@me的值在array("1", "3", "5")中,它就会被替换成"special-class",否则保持原样(因为str_replace找不到匹配项,会返回原始字符串),但由于我们只需要一个类名,所以这个写法巧妙地实现了判断。
使用 {dede:if} 标签(不推荐,有局限性)
DedeCMS 提供了一个专门的 {dede:if} 标签,但它有非常严格的限制,通常不能直接用于 {dede:channel} 的循环内部。
核心思路
{dede:if} 通常用于 {dede:arclist} 或 {dede:list} 等列表标签的循环体内部,来判断文章的某个字段(如 arctypeid, flag 等)。
示例代码(错误用法,会无效)
<!-- 这种写法在 {dede:channel} 内部通常是无效的 -->
{dede:channel type='top' row='8'}
{dede:if $type['topid'] == 0}
<li><a href="[field:typelink/]">[field:typename/]</a></li>
{/dede:if}
{/dede:channel}
为什么它不常用?
- 作用域限制:
{dede:if}的作用域通常与{dede:arclist}等数据标签绑定,不能随意套用在{dede:channel}的$type变量上。 - 灵活性差:它无法像
runphp那样进行复杂的逻辑运算和字符串处理。
正确的 {dede:if} 用法示例(用于文章列表):
{dede:arclist row='10'}
{dede:if $typeid == 1}
<div class="special-post">
<a href="[field:arcurl/]">[field:title/]</a>
</div>
{/dede:if}
{dede:if $typeid != 1}
<div class="normal-post">
<a href="[field:arcurl/]">[field:title/]</a>
</div>
{/dede:if}
{/dede:arclist}
总结与最佳实践
| 方法 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
runphp |
功能最强大,逻辑最灵活,可以处理任何复杂的判断和字符串操作。 | 语法稍复杂,需要一点PHP基础。 | 几乎所有情况下的栏目判断,特别是导航栏高亮、顶级/子栏目样式区分等。 |
INSTR |
语法简洁,代码量少。 | 仅适用于判断ID是否在特定列表中的场景,不够通用。 | 快速为特定ID的栏目添加特殊样式。 |
{dede:if} |
语法直观。 | 局限性大,不适用于{dede:channel},主要用于文章列表的字段判断。 |
在 {dede:arclist} 或 {dede:list} 循环中判断文章的属性。 |
在进行 {dede:channel} 的 if 判断时,请优先使用 runphp 方法,它虽然需要你写一点PHP代码,但它是解决此类问题的标准且最可靠的方案,能让你完全掌控模板的逻辑。
