Discuz! 的模板系统是基于文件和目录的,通过修改特定的模板文件,你可以自由地改变列表页的样式和布局。

discuz分类信息列表页模板
(图片来源网络,侵删)

核心文件位置

分类信息列表页的模板文件主要位于以下目录:

/source/class/table/ - 数据逻辑层:这里不直接涉及模板,但包含了获取列表数据的PHP代码,如 table_forum_forumdisplay.php(虽然名字是forumdisplay,但分类信息模块复用了很多其逻辑)。 /template/ - 模板根目录:这是存放所有模板文件的地方。 /template/你的默认模板目录/ - 具体模板文件目录defaultmobile 等,我们主要修改这里的文件。

最核心的模板文件是:

/template/你的默认模板目录/category/list.htm

discuz分类信息列表页模板
(图片来源网络,侵删)

这个文件是控制分类信息列表页主体结构循环输出的核心。


模板文件结构详解 (list.htm)

打开 list.htm,你会发现它主要由 Discuz! 的模板标签(PHP代码)和HTML/CSS/JS构成,其结构通常如下:

{template common/header}  <!-- 调用公共头部,如 <head>, <body>, 顶部导航等 -->
<!-- 页面主体内容区开始 -->
<div id="pt" class="bm cl">
    <div class="z">
        <a href="./" class="nvhm" title="{lang homepage}">$_G[setting][bbname]</a> <em>›</em>
        {if $forum['ismoderator']}
        <a href="forum.php?mod=moderate&fid=$_G[fid]">{lang moderate}</a> <em>›</em>
        {/if}
        <a href="forum.php?mod=list&fid=$_G[fid]">$_G[forum][name]</a>
    </div>
</div>
<div id="ct" class="ct2 wp cl">
    <!-- 左侧主要内容区 -->
    <div class="mn">
        <!-- 筛选和排序工具栏 -->
        <div class="bm bw0 cl">
            <!-- 这里是筛选条件,如地区、行业、价格等 -->
            {subtemplate category/filter} <!-- 通常筛选器会调用一个子模板 -->
            <!-- 这里是排序方式,如最新发布、价格排序等 -->
            <div class="tb tb_h cl">
                <div class="y">
                    <a href="javascript:;" onclick="setcookie('forumviewmode', 'table', 864000);location.reload();" {if !empty($_G['cookie']['forumviewmode']) && $_G['cookie']['forumviewmode'] == 'table'}class="a"{/if}>{lang table_view}</a>
                    <a href="javascript:;" onclick="setcookie('forumviewmode', 'list', 864000);location.reload();" {if empty($_G['cookie']['forumviewmode']) || $_G['cookie']['forumviewmode'] == 'list'}class="a"{/if}>{lang list_view}</a>
                </div>
            </div>
        </div>
        <!-- 信息列表主体 -->
        <div class="bm">
            <!-- 列表头部,显示总信息数等 -->
            <div class="bm_h cl">
                <span class="y">
                    <!-- 分页代码 -->
                    {if $multipage}
                        <div class="pgs cl">$multipage</div>
                    {/if}
                </span>
                <h2>{lang list_posts} ({$total})</h2>
            </div>
            <!-- 列表项循环区域 -->
            <div class="bm_c">
                <!-- 列表项的HTML结构,这里通常是一个表格或div列表 -->
                <!-- {loop $list $var} ... {/loop} 是循环标签 -->
                {loop $list $thread}
                    <table summary="forum_$thread[tid]" cellpadding="0" cellspacing="0" class="olt">
                        <tr>
                            <td class="icn">
                                <!-- 帖子图标、置顶、加精等标记 -->
                                {if $thread['typeid']}
                                <a href="forum.php?mod=list&fid=$_G[fid]&typeid=$thread[typeid]" target="_blank">
                                    <img src="{STATICURL}image/common/type_$thread[typeid].gif" alt="$thread[typename]" />
                                </a>
                                {/if}
                                <a href="forum.php?mod=viewthread&tid=$thread[tid]" {if $thread[highlight]}class="$thread[highlight]"{/if} id="thread_title_$thread[tid]">
                                    <!-- 这里是帖子的标题 -->
                                    $thread[subject]
                                </a>
                            </td>
                            <td class="c">
                                <!-- 作者信息 -->
                                <a href="home.php?mod=space&uid=$thread[authorid]" c="1">$thread[author]</a>
                                <br />
                                <span class="xs">
                                    <!-- 发布时间 -->
                                    {echo dgmdate($thread[dateline], 'u')}
                                </span>
                            </td>
                            <td class="a">
                                <!-- 回复数/浏览数 -->
                                {if $thread[replies]}
                                    <a href="forum.php?mod=viewthread&tid=$thread[tid]&page={$thread[pages]}&extra=page%3D1#lastpost">$thread[replies]</a>
                                {/if}
                                / $thread[views]
                            </td>
                        </tr>
                        <!-- 如果启用了自定义字段,这里会循环显示 -->
                        {if $thread['fields']}
                        <tr>
                            <td colspan="3">
                                {loop $thread['fields'] $field}
                                    <div class="cl">
                                        <span class="y">{lang category:$field['title']}</span>
                                        <span>$field[value]</span>
                                    </div>
                                {/loop}
                            </td>
                        </tr>
                        {/if}
                    </table>
                {/loop}
            </div>
            <!-- 列表底部,再次显示分页 -->
            <div class="bm_b cl">
                {if $multipage}
                    <div class="pgs cl">$multipage</div>
                {/if}
            </div>
        </div>
    </div>
    <!-- 右侧边栏 -->
    <div class="sd">
        <!-- 这里可以调用其他子模板,如热门信息、最新信息、分类导航等 -->
        {subtemplate category/right_sidebar} <!-- 这是一个示例,具体取决于模板设置 -->
    </div>
</div>
{template common/footer} <!-- 调用公共底部,如版权信息、页脚导航等 -->

关键模板标签和数据

数据变量

这些变量通常由后台PHP代码 (source/class/table/...) 查询数据库后赋值给模板引擎。

  • $_G['forum']: 当前分类的信息,如名称、ID等。
  • $list: 一个数组,包含了当前页所有信息帖子的数据,在 {loop $list $thread} 中,$thread 就代表每一个帖子。
  • $thread['tid']: 帖子ID。
  • $thread['subject']: 帖子标题。
  • $thread['author']: 帖子作者。
  • $thread['authorid']: 帖子作者ID。
  • $thread[dateline]: 帖子发布时间(时间戳)。
  • $thread[replies]: 回复数。
  • $thread[views]: 浏览数。
  • $thread['typeid']: 帖子所属的分类ID(二级分类)。
  • $thread['typename']: 帖子所属的分类名称。
  • $thread['fields']: 非常重要! 这是帖子自定义字段的数组,如果你的分类信息有“价格”、“面积”、“联系电话”等字段,它们的数据就存在这里。
  • $total: 当前分类下的信息总数。
  • $multipage: 分页导航的HTML代码。

核心标签

  • {template common/header} / {template common/footer}: 公共头部和尾部。
  • {loop $list $thread} / {/loop}: 循环标签,遍历 $list 数组,对每个帖子执行一次循环体内的代码。
  • {subtemplate ...}: 调用子模板,筛选器、侧边栏等通常会拆分成独立的子模板文件,方便管理和复用。
  • {lang ...}: 语言包标签,用于显示多语言支持的文本。
  • {STATICURL}: 站点静态资源目录的URL。

常见修改与自定义

修改列表项的显示样式

最常见的需求是改变列表项的布局,默认是表格布局,你可以将其改为更现代的 div 布局。

示例:将表格改为卡片式布局

list.htm{loop $list $thread} 部分,将 <table> 标签替换为 div

<!-- 原始表格结构 -->
{loop $list $thread}
    <table summary="forum_$thread[tid]" cellpadding="0" cellspacing="0" class="olt">
        ...
    </table>
{/loop}
<!-- 修改为卡片式div结构 -->
{loop $list $thread}
    <div class="info-card cl">
        <div class="card-main">
            <h3>
                <a href="forum.php?mod=viewthread&tid=$thread[tid]">
                    $thread[subject]
                </a>
            </h3>
            <div class="card-meta">
                <span class="author">作者: <a href="home.php?mod=space&uid=$thread[authorid]">$thread[author]</a></span>
                <span class="time">{echo dgmdate($thread[dateline], 'Y-m-d H:i')}</span>
            </div>
            <!-- 循环显示自定义字段 -->
            {if $thread['fields']}
                <div class="card-fields">
                    {loop $thread['fields'] $field}
                        <p><strong>{lang category:$field['title']}:</strong> $field[value]</p>
                    {/loop}
                </div>
            {/if}
        </div>
        <div class="card-stats">
            <span>浏览: $thread[views]</span>
            <span>回复: $thread[replies]</span>
        </div>
    </div>
{/loop}

在CSS文件(通常是 template/你的模板目录/css/common.css)中添加 .info-card, .card-main 等样式,即可实现美观的卡片效果。

调整筛选器

筛选器通常由一个子模板控制,category/filter.htm,你可以直接编辑这个文件来增删筛选条件,或者调整其样式和布局。

调整分页样式

分页的HTML代码由 $multipage 变量生成,这个变量是在PHP代码中生成的,如果你想彻底改变分页的样式,可能需要修改生成 $multipage 的PHP代码,或者用JavaScript来重新渲染它,但通常,通过CSS来美化 $multipage 生成的HTML结构是最简单的方法。

修改侧边栏

{subtemplate category/right_sidebar} 或类似标签调用,你可以编辑对应的子模板文件,或者直接在 list.htm 中写死HTML内容来添加你想要的模块,热门信息”、“最新发布”、“相关推荐”等。


调试与开发技巧

  1. 开启模板调试模式: 在 config/config_global.php 文件中,找到 $_G['debug'],将其设置为 7

    $_G['debug'] = 7;

    这样,页面底部会显示当前使用的模板路径、加载的模板文件列表以及SQL查询语句,非常有助于排查问题。

  2. 使用浏览器开发者工具: 这是前端开发必备,右键 -> 检查,你可以实时查看HTML结构、修改CSS样式并立即看到效果,定位到对应的CSS类名后再去编辑CSS文件。

  3. 从默认模板开始修改: 如果你不确定自己的修改是否正确,建议先复制一份 default 模板,命名为 my_custom_template,然后对这个新模板进行修改,这样即使改坏了,也不会影响网站正在使用的模板。

  4. 理解模板继承: 一些模板框架(如Discuz! X3.5之后的某些版本)可能会引入类似 {template header} 这样的继承机制,但Discuz!的核心仍然是文件包含,理解 {template xxx} 是将 xxx.htm 文件的内容原样插入到当前位置即可。

希望这份详细的解析能帮助你更好地理解和修改Discuz!分类信息列表页模板!