PHPCMS 的模板引擎基于 ThinkTemplate,其核心语法是 {$variable} 和 volist 标签,栏目循环主要依赖于 volist 标签来遍历系统分配过来的栏目数据。

(图片来源网络,侵删)
核心思路
- 获取数据:在 PHP 控制器中,通过
param方法获取当前频道的 ID,然后调用模型(如content_model)的category()方法获取该频道下的所有栏目数据。 - 分配数据:使用
template对象的assign()方法,将获取到的栏目数据分配给一个模板变量,$cats。 - 模板渲染:在频道模板文件(通常是
category.php)中,使用volist标签遍历这个$cats变量,并输出每个栏目的信息(如名称、链接、缩略图等)。
第一步:控制器中的代码 (PHP)
频道页面的逻辑处理文件位于 phpcms/modules/content/index.php,你需要找到 category() 方法或在其基础上进行修改。
假设我们要在首页(index.php)的 index() 方法中调用某个指定频道的子栏目,或者在 category() 方法中调用当前频道的子栏目。
示例:在首页调用指定频道的所有一级栏目
打开 phpcms/modules/content/index.php,找到 index() 方法。
<?php
defined('IN_PHPCMS') or exit('No permission resources.');
class index {
function __construct() {
// 实例化内容模型
$this->content_db = pc_base::load_model('content_model');
// 实例化栏目模型
$this->category_db = pc_base::load_model('category_model');
}
public function init() {
// ... 首页其他逻辑 ...
}
// 假设这是我们要修改的首页方法
public function index() {
// 1. 获取数据
// 假设我们要调用 ID 为 1 的频道下的所有栏目
$catid = 1;
// 调用 category_model 的 category 方法获取栏目列表
// 第一个参数是父栏目ID,第二个参数是显示级别(0表示所有子栏目)
$cats = $this->category_db->category($catid, 0, 'catid ASC');
// 2. 分配数据
// 将 $cats 数组分配给模板变量 $navcats
template()->assign('navcats', $cats);
// 3. 渲染模板
// 加载首页模板文件
include template('content', 'index');
}
}
代码解释:

(图片来源网络,侵删)
$this->category_db = pc_base::load_model('category_model');:加载栏目数据模型。$catid = 1;:设置你要调用的父频道/栏目的 ID,你可以通过param('catid')来动态获取当前栏目 ID。$cats = $this->category_db->category($catid, 0, 'catid ASC');:这是核心方法。category($parentid, $type, $order)方法用于获取栏目列表。$parentid: 父栏目 ID,我们传入$catid,表示获取该栏目下的所有子栏目。$type: 显示级别。0表示获取所有子栏目(无限级),1表示只获取直接子栏目(一级),通常我们用0。$order: 排序方式。'catid ASC'表示按栏目 ID 升序排列,你也可以用'listorder ASC'按后台设置的字段排序。
template()->assign('navcats', $cats);:将获取到的$cats数组变量命名为navcats,并传递给模板。include template('content', 'index');:加载phpcms/templates/default/content/index.html这个模板文件。
第二步:模板中的代码 (HTML)
打开你的频道模板文件,phpcms/templates/default/content/index.html。
示例:在首页顶部调用一个主导航栏
假设我们想在首页顶部循环调用 ID 为 1 的频道的所有子栏目作为主导航。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">首页 - 我的PHPCMS网站</title>
</head>
<body>
<!-- 这是我们添加的栏目循环部分 -->
<div class="main-nav">
<ul>
<!--
volist name="navcats" id="cat"
name: 对应PHP中 assign 的变量名,这里是 'navcats'
id: 循环中每个元素的临时变量名,可以自定义,这里用 'cat'
-->
{volist name="navcats" id="cat"}
<li>
<!--
循环输出每个栏目的信息
$cat['字段名']: 对应数据库 phpcms_category 表中的字段
-->
<a href="{$cat.url}" title="{$cat.catname}">
{$cat.catname}
</a>
</li>
{/volist}
</ul>
</div>
<div class="main-content">
<!-- 页面其他内容... -->
</div>
</body>
</html>
模板标签详解:
{volist name="navcats" id="cat"}:name="navcats":指定要遍历的变量,这个变量名必须和 PHP 中assign()的第一个参数完全一致。id="cat":定义一个循环内的临时变量,用来代表当前循环到的那个栏目数组,在{/volist}内部,所有对当前栏目的操作都通过$cat来访问。
{$cat.url}:输出栏目的链接地址,PHPCMS 会自动根据栏目类型(列表、首页、外部链接等)生成正确的 URL。{$cat.catname}:输出栏目的名称。{$cat.catid}:输出栏目的 ID。{$cat.type}:输出栏目的类型(1单页 2列表 3链接)。{$cat.listorder}:输出栏目的排序数字。{$cat.thumb}:输出栏目的缩略图地址(如果设置了的话)。
常用字段列表
在 volist 循环中,你可以通过 $cat['字段名'] 的方式调用 phpcms_category 表中的几乎所有字段,常用字段包括:

(图片来源网络,侵删)
| 字段名 | 说明 | 示例 |
|---|---|---|
catname |
栏目名称 | {$cat.catname} |
url |
栏目链接地址 | <a href="{$cat.url}"> |
catid |
栏目ID | id="cat-{$cat.catid}" |
type |
栏目类型 (1单页, 2列表, 3链接) | if($cat.type == 2) |
listorder |
后台排序数字 | order by {$cat.listorder} |
description |
栏目描述 | {$cat.description} |
keywords |
栏目关键词 | {$cat.keywords} |
parentid |
父栏目ID | if($cat.parentid == 1) |
child |
是否有子栏目 (1有, 0无) | if($cat.child) |
ismenu |
是否显示 in menu (1显示, 0不显示) | if($cat.ismenu) |
thumb |
栏目缩略图 | <img src="{$cat.thumb}" alt="{$cat.catname}"> |
高级用法与技巧
循环指定层级的栏目
如果只想调用直接子栏目(一级栏目),而不是所有子栏目,修改 PHP 代码即可:
// 在控制器中 // 将第二个参数改为 1 $cats = $this->category_db->category($catid, 1, 'listorder ASC');
在循环中进行判断
在模板中,你可以使用 if 标签进行判断,实现不同的样式或逻辑。
{volist name="navcats" id="cat"}
<li {if condition="$cat['child'] == 1"}class="has-submenu"{/if}>
<a href="{$cat.url}">{$cat.catname}</a>
<!-- 如果有子栏目,再循环一次 -->
{if condition="$cat['child'] == 1"}
<ul class="submenu">
{volist name="$cat['arrchildid']" id="childcatid"}
{php $childcat = $this->category_db->get_one(array('catid'=>$childcatid));}
<li><a href="{$childcat.url}">{$childcat.catname}</a></li>
{/volist}
</ul>
{/if}
</li>
{/volist}
注意:$cat['arrchildid'] 是一个包含所有子孙栏目 ID 的字符串(如 "5,6,7"),需要再次循环查询每个子栏目的详细信息。
调用当前频道的同级栏目
有时候你可能需要调用和当前频道同级的所有栏目。
// 在 category.php 控制器中
public function category() {
$catid = intval($_GET['catid']);
$CATEGORYS = getcache('category_content', 'commons'); // 获取全站缓存
// 获取当前栏目的父栏目ID
$parentid = $CATEGORYS[$catid]['parentid'];
// 获取父栏目下的所有子栏目(即当前栏目的同级栏目)
$sibling_cats = $this->category_db->category($parentid, 1, 'listorder ASC');
template()->assign('sibling_cats', $sibling_cats);
// ... 其他逻辑
}
然后在模板中 {volist name="sibling_cats" ...} 即可。
调用 PHPCMS 栏目循环的流程可以概括为:
- PHP (后端):
- 加载
category_model。 - 使用
$model->category($parentid, $type, $order)获取栏目数组。 - 使用
$template->assign('var_name', $array)将数据传递给模板。
- 加载
- HTML (模板):
- 使用
{volist name="var_name" id="item"}遍历数组。 - 在循环内部使用
{$item['field_name']}输出具体字段。
- 使用
掌握这个流程,你就可以灵活地在网站的任何位置实现栏目的动态调用了。
