首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >PbootCMS二次开发实战:创建自定义页面与功能扩展

PbootCMS二次开发实战:创建自定义页面与功能扩展

原创
作者头像
小唐同学.
修改2025-09-29 18:32:59
修改2025-09-29 18:32:59
4510
举报
文章被收录于专栏:PbootCMS开发PbootCMS开发
PbootCMS作为一款国内主流的开源CMS系统,本文将深入探讨PbootCMS创建自定义页面与功能扩展,带你全面掌握这一功能的实战应用。

提示:实际开发请根据具体环境和需求进行调整。建议在开发前备份原有文件和数据,以免造成不必要的损失。

一、二次开发概述

1.1 核心目录结构

以下是PbootCMS的主要目录结构及其作用:

目录/文件

说明

/apps

应用目录,包含主要业务逻辑

/apps/admin

后台管理应用

/apps/home

前台应用

/apps/api

API接口应用

/apps/common

公共目录

/config

配置文件目录

/config/config.php

系统主配置文件

/config/database.php

数据库配置文件

/config/route.php

路由配置文件

/core

框架核心文件

/template

模板文件目录

/static

静态资源目录

/runtime

运行时缓存目录

index.php

前台入口文件

admin.php

后台入口文件

二、二次开发实战:创建自定义产品展示页面

下面通过一个实际案例演示如何在PbootCMS中创建自定义产品展示页面,包括控制器、模板和路由配置。

2.1 创建控制器

/apps/home/controller/目录下创建ProductController.php文件:

代码语言:javascript
复制
<?php
// /apps/home/controller/ProductController.php

/**
 * 产品展示控制器
 * 演示PbootCMS二次开发流程
 */
class ProductController extends Controller
{
    
    /**
     * 产品列表页
     */
    public function index()
    {
        // 接收参数并过滤
        $page = get('page', 'int') ?: 1;
        $keywords = get('keywords', 'vars');
        
        // 构建查询条件
        $where = array();
        if ($keywords) {
            $where['title'] = ['like', '%' . $keywords . '%'];
        }
        
        // 设置每页显示数量
        $pageSize = 10;
        
        // 调用模型获取数据
        $data = $this->model->content->getList($where, $page, $pageSize, 'date desc');
        
        // 分配数据到模板
        $this->assign([
            'productList' => $data->data, // 产品列表数据
            'page' => $data->page, // 分页数据
            'keywords' => $keywords // 搜索关键词
        ]);
        
        // 显示模板
        $this->display('product_list.html');
    }
    
    /**
     * 产品详情页
     */
    public function detail()
    {
        // 获取产品ID
        $id = get('id', 'int');
        if (!$id) {
            error('产品ID不能为空!');
        }
        
        // 读取产品详情
        $product = $this->model->content->getDetail($id);
        if (!$product) {
            error('产品不存在!');
        }
        
        // 获取相关产品(使用tags标签关联)
        $relatedWhere = [
            'tags' => $product->tags,
            'id' => ['neq', $id] // 排除当前产品
        ];
        
        $relatedProducts = $this->model->content->getList($relatedWhere, 1, 6, 'random');
        
        // 分配数据到模板
        $this->assign([
            'product' => $product,
            'relatedProducts' => $relatedProducts->data
        ]);
        
        // 显示模板
        $this->display('product_detail.html');
    }
    
    /**
     * 产品搜索API接口
     * 返回JSON格式数据
     */
    public function search()
    {
        // 只允许AJAX访问
        if (!is_ajax()) {
            json(0, '非法访问!');
        }
        
        $keywords = get('keywords', 'vars');
        $page = get('page', 'int') ?: 1;
        $pageSize = 12;
        
        $where = array();
        if ($keywords) {
            $where['title'] = ['like', '%' . $keywords . '%'];
        }
        
        $data = $this->model->content->getList($where, $page, $pageSize, 'date desc');
        
        // 返回JSON数据
        json(1, 'success', [
            'list' => $data->data,
            'page' => $data->page->toArray(),
            'keywords' => $keywords
        ]);
    }
}
?>

2.2 创建模板文件

/template/default/目录下创建产品列表模板product_list.html

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>产品列表 - {pboot:sitetitle}</title>
    <meta name="keywords" content="{pboot:sitekeywords}">
    <meta name="description" content="{pboot:sitedescription}">
    <link rel="stylesheet" href="/static/css/product.css">
</head>
<body>
    {include file='header.html'}
    
    <div class="container">
        <div class="breadcrumb">
            当前位置:<a href="{pboot:sitelink}">首页</a> > 产品中心
        </div>
        
        <!-- 搜索框 -->
        <div class="search-box">
            <form action="{content:link}" method="get">
                <input type="text" name="keywords" value="{content:keywords}" placeholder="输入产品关键词">
                <button type="submit">搜索</button>
            </form>
        </div>
        
        <!-- 产品列表 -->
        <div class="product-list">
            {pboot:list scode=2 num=12 page=1 order='date desc'}
            <div class="product-item">
                <div class="product-image">
                    <a href="[list:link]">
                        <img src="[list:ico]" alt="[list:title]" onerror="this.src='/static/images/default.jpg'">
                    </a>
                </div>
                <div class="product-info">
                    <h3><a href="[list:link]">[list:title]</a></h3>
                    <p class="product-desc">[list:description lenth=50]</p>
                    <div class="product-meta">
                        <span class="date">[list:date style=Y-m-d]</span>
                        <span class="visits">浏览:[list:visits]</span>
                    </div>
                </div>
            </div>
            {/pboot:list}
        </div>
        
        <!-- 分页 -->
        <div class="pagination">
            {content:page}
        </div>
    </div>
    
    {include file='footer.html'}
    
    <script src="/static/js/product.js"></script>
</body>
</html>

/template/default/目录下创建产品详情模板product_detail.html

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>{content:title} - {pboot:sitetitle}</title>
    <meta name="keywords" content="{content:keywords}">
    <meta name="description" content="{content:description}">
    <link rel="stylesheet" href="/static/css/product.css">
</head>
<body>
    {include file='header.html'}
    
    <div class="container">
        <div class="breadcrumb">
            当前位置:<a href="{pboot:sitelink}">首页</a> > 
            <a href="{sort:link}">{sort:name}</a> > 
            {content:title}
        </div>
        
        <!-- 产品详情 -->
        <div class="product-detail">
            <div class="detail-header">
                <h1>{content:title}</h1>
                <div class="meta">
                    <span>发布时间:{content:date style=Y-m-d H:i}</span>
                    <span>浏览次数:{content:visits}</span>
                    <span>作者:{content:author}</span>
                </div>
            </div>
            
            <div class="detail-content">
                {content:content}
            </div>
            
            <!-- 多图展示 -->
            {pboot:if({content:pics})}
            <div class="product-gallery">
                <h3>产品图集</h3>
                <div class="gallery-list">
                    {pboot:list pics={content:pics}}
                    <div class="gallery-item">
                        <img src="[list:value]" alt="产品图片">
                    </div>
                    {/pboot:list}
                </div>
            </div>
            {/pboot:if}
        </div>
        
        <!-- 相关产品 -->
        <div class="related-products">
            <h3>相关产品</h3>
            <div class="related-list">
                {pboot:list scode={sort:scode} num=6 filter=id!={content:id} order=random}
                <div class="related-item">
                    <a href="[list:link]">
                        <img src="[list:ico]" alt="[list:title]">
                        <span>[list:title]</span>
                    </a>
                </div>
                {/pboot:list}
            </div>
        </div>
    </div>
    
    {include file='footer.html'}
</body>
</html>

2.3 配置路由

/config/route.php文件中添加自定义路由规则:

代码语言:javascript
复制
<?php
// /config/route.php

return array(
    // 默认路由规则
    'default' => 'home/Index/index',
    
    // 产品模块路由
    'product.html' => 'home/Product/index', // 产品列表页
    'product/detail/:id' => 'home/Product/detail', // 产品详情页
    'api/product/search' => 'home/Product/search', // 产品搜索API
    
    // 更多自定义路由...
);
?>

2.4 创建静态资源文件

/static/css/目录下创建product.css样式文件:

代码语言:javascript
复制
/* /static/css/product.css */

.product-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 20px;
    margin: 20px 0;
}

.product-item {
    border: 1px solid #eaeaea;
    border-radius: 8px;
    overflow: hidden;
    transition: transform 0.3s ease;
}

.product-item:hover {
    transform: translateY(-5px);
    box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}

.product-image img {
    width: 100%;
    height: 200px;
    object-fit: cover;
}

.product-info {
    padding: 15px;
}

.product-info h3 {
    margin: 0 0 10px 0;
}

.product-info h3 a {
    color: #333;
    text-decoration: none;
}

.product-desc {
    color: #666;
    line-height: 1.6;
    margin-bottom: 10px;
}

.product-meta {
    display: flex;
    justify-content: space-between;
    color: #999;
    font-size: 12px;
}

/static/js/目录下创建product.js脚本文件:

代码语言:javascript
复制
// /static/js/product.js

// 产品搜索功能
document.addEventListener('DOMContentLoaded', function() {
    // 实时搜索建议
    const searchInput = document.querySelector('input[name="keywords"]');
    if (searchInput) {
        let timeout = null;
        
        searchInput.addEventListener('input', function() {
            clearTimeout(timeout);
            timeout = setTimeout(function() {
                const keywords = searchInput.value.trim();
                if (keywords.length > 1) {
                    fetchSearchSuggestions(keywords);
                }
            }, 500);
        });
    }
    
    // 产品图片懒加载
    if ('IntersectionObserver' in window) {
        const imageObserver = new IntersectionObserver((entries, observer) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    const img = entry.target;
                    img.src = img.dataset.src;
                    img.classList.remove('lazy');
                    imageObserver.unobserve(img);
                }
            });
        });
        
        document.querySelectorAll('img[data-src]').forEach(img => {
            imageObserver.observe(img);
        });
    }
});

// 获取搜索建议
async function fetchSearchSuggestions(keywords) {
    try {
        const response = await fetch('/api/product/search?keywords=' + encodeURIComponent(keywords));
        const data = await response.json();
        
        if (data.code === 1) {
            displaySearchSuggestions(data.data.list);
        }
    } catch (error) {
        console.error('搜索请求失败:', error);
    }
}

// 显示搜索建议
function displaySearchSuggestions(products) {
    // 实现搜索建议显示逻辑
    console.log('搜索建议:', products);
}

三、高级开发技巧

3.1 使用PbootCMS标签进行数据调用

PbootCMS提供了强大的模板标签系统,可以方便地调用各种数据:

代码语言:javascript
复制
<!-- 调用指定栏目的内容列表 -->
{pboot:list scode=1,2,3 num=5 order='date desc' isrecommend=1}
<div class="news-item">
    <a href="[list:link]">[list:title]</a>
    <span class="date">[list:date style=Y-m-d]</span>
</div>
{/pboot:list}

<!-- 调用站点信息 -->
站点名称:{pboot:sitetitle}
站点关键词:{pboot:sitekeywords}
站点描述:{pboot:sitedescription}

<!-- 调用导航菜单 -->
{pboot:nav}
<a href="[nav:link]">[nav:name]</a>
{/pboot:nav}

3.2 数据库操作与模型使用

在控制器中进行数据库操作

代码语言:javascript
复制
// 在控制器方法中使用模型
public function customMethod()
{
    // 使用内容模型
    $contentModel = $this->model->content;
    
    // 复杂查询
    $where = [
        'scode' => [1, 2, 3], // 栏目编码
        'title' => ['like', '%关键词%'],
        'visits' => ['>', 100]
    ];
    
    $list = $contentModel->getList($where, 1, 10, 'visits desc');
    
    // 自定义SQL查询(谨慎使用)
    $sql = "SELECT * FROM ay_content WHERE scode IN (1,2,3) ORDER BY date DESC LIMIT 10";
    $result = $this->model->query($sql);
}

四、调试与优化

4.1 开启调试模式

/config/config.php中开启调试模式

代码语言:javascript
复制
// /config/config.php
return array(
    'debug' => true, // 开启调试模式
    'error_level' => E_ALL, // 错误报告级别
    // 其他配置...
);

4.2 性能优化建议

  1. 启用缓存:合理使用{pboot:cache}标签缓存不常变化的内容
  2. 静态资源优化:合并CSS/JS文件,使用CDN加速
  3. 数据库优化:为常用查询字段添加索引,避免频繁复杂查询
  4. 图片优化:使用适当的图片格式和压缩技术

实际开发请根据具体环境和需求进行调整。建议在开发前备份原有文件和数据,以免造成不必要的损失。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 提示:实际开发请根据具体环境和需求进行调整。建议在开发前备份原有文件和数据,以免造成不必要的损失。
  • 一、二次开发概述
    • 1.1 核心目录结构
    • 二、二次开发实战:创建自定义产品展示页面
      • 2.1 创建控制器
      • 2.2 创建模板文件
      • 2.3 配置路由
      • 2.4 创建静态资源文件
    • 三、高级开发技巧
      • 3.1 使用PbootCMS标签进行数据调用
      • 3.2 数据库操作与模型使用
    • 四、调试与优化
      • 4.1 开启调试模式
      • 4.2 性能优化建议
    • 实际开发请根据具体环境和需求进行调整。建议在开发前备份原有文件和数据,以免造成不必要的损失。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档