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

phpcms 频道模板栏目循环调用
(图片来源网络,侵删)

核心思路

  1. 获取数据:在 PHP 控制器中,通过 param 方法获取当前频道的 ID,然后调用模型(如 content_model)的 category() 方法获取该频道下的所有栏目数据。
  2. 分配数据:使用 template 对象的 assign() 方法,将获取到的栏目数据分配给一个模板变量,$cats
  3. 模板渲染:在频道模板文件(通常是 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');
    }
}

代码解释

phpcms 频道模板栏目循环调用
(图片来源网络,侵删)
  • $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 表中的几乎所有字段,常用字段包括:

phpcms 频道模板栏目循环调用
(图片来源网络,侵删)
字段名 说明 示例
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 栏目循环的流程可以概括为:

  1. PHP (后端):
    • 加载 category_model
    • 使用 $model->category($parentid, $type, $order) 获取栏目数组。
    • 使用 $template->assign('var_name', $array) 将数据传递给模板。
  2. HTML (模板):
    • 使用 {volist name="var_name" id="item"} 遍历数组。
    • 在循环内部使用 {$item['field_name']} 输出具体字段。

掌握这个流程,你就可以灵活地在网站的任何位置实现栏目的动态调用了。