兴趣圈子主题模板 V1.1
主题分类: 博客资讯
演示地址: 暂无演示,查看截图
CMS版本: 最低 V 7.2
主题价格: 免费
发布日期: 2026-10-09 11:55:08
下载安装 提示:下载为默认主题,必须登后台--主题中心--安装兴趣圈子主题模板方可。

兴趣圈子主题模板 主题说明

简介:复刻经典兴趣圈子布局,双栏卡片式设计,自动适配 PC 与移动端。首页三 TAB 切换、右侧头条资讯 / 图新鲜 / 推荐栏目 / 搜索标签 / 友情链接,多图文章自动成网格展示。

主题截图

首页截图
首页截图
分类页截图
分类页截图
文章详情页截图
文章详情页截图

安装方法

  1. 下载逗号CMS → 登录后台 → 主题管理 → 主题列表,找到「兴趣圈子主题模板」主题,点击免费安装。
  2. 进入 后台 → 网站设置 → 顶部导航,配置顶部导航及链接。
  3. 进入 后台 → 网站设置 → 参数设置,配置首页、分类页、文章页的文章显示数量。
  4. 进入网站设置 → SEO 设置,配置首页、文章分类列表页、文章详情页的 SEO 信息。
  5. 可选:进入企业管理 → 人员管理,配置人员头像和名称作为文章作者。

功能特色

经典圈子风格布局

复刻经典圈子首页双栏卡片布局,左侧内容主区 + 右侧信息侧栏,信息密度高。

三 TAB 切换

最新发布 / 推荐话题 / 热门话题三个 TAB 无缝切换,展示不同维度的文章列表。

多图网格展示

文章正文含多张图片时,自动以 3 列网格展示,最多 2 行共 6 张,1 张图仍显示大图。

热搜标签

右侧栏内置搜索标签模块,读取后台热搜词,一键直达热搜聚合页。

头条资讯换一批

头条资讯每次随机抽取 8 条展示,点击「换一批」即可刷新,增加浏览趣味。

作者头像

文章列表显示作者头像,自动从后台「人员管理」匹配;未匹配到则显示默认头像。

PC / 移动自适应

PC 端双栏布局,移动端自动单栏,字号适当放大,触摸体验友好。

广告位支持

支持首页轮播图、顶部横幅、底部悬浮、文章阅读全文等系统内置广告位。

顶部导航配置

主题顶部导航完全由后台「网站设置 → 顶部导航」控制,可自由配置菜单项。

添加导航

  1. 后台 → 系统管理 → 网站设置 → 顶部导航
  2. 点击「添加导航」,填写导航名称
  3. 选择链接类型:
    • 内部链接:可选择首页、文章频道、产品频道、留言本、热搜标签,以及任意分类
    • 外部链接:直接填写完整网址
  4. 设置打开方式(当前窗口 / 新窗口)、状态(启用 / 禁用)、排序(数字越小越靠前)
  5. 点击「添加导航」保存

导航缓存

后台配置导航后,系统会自动生成缓存文件 /cache/nav_cache.php,前台读取缓存,零数据库查询。

如果修改导航后前台没有立即生效,可能原因:1) 网站开启了页面缓存,需到「缓存管理」清空;2) 浏览器缓存了旧页面,按 Ctrl + F5 强制刷新。

页面列表

主题包含以下页面文件,全部位于 /templates/quanzi/ 目录:

文件名页面说明URL
header.php公共头部(导航 + 搜索)-
footer.php公共底部(联系方式 + 备案)-
index.php网站首页/
category.php分类列表页 / 搜索页/list.html、/category-x.html、/rs/关键词
article.php文章详情页/article-x.html
search_rs.php搜索标签聚合页/rs
style.css主题全局样式-

其他资源

文件说明
/templates/quanzi/style.css主题全局样式(含响应式)
/templates/quanzi/route.php主题路由(可选,默认路由已包含全套)
本主题所有页面均由系统默认前端路由自动分发,无需替换「前端路由管理」中的配置。如果安装时覆盖了默认路由,导致页面 404,请到「前端路由管理」点击「恢复默认」。

广告位配置

兴趣圈子主题支持以下系统内置广告位:

广告位调用位置展示模式
网站轮播图首页左侧顶部轮播
网站横幅顶部导航下方(所有页面)随机
网站底部悬浮页面底部固定悬浮随机
文章页阅读全文文章阅读全文时弹窗随机

配置首页轮播图

  1. 后台 → 内容管理 → 广告管理 → 网站轮播图
  2. 点击「广告设置」→「添加广告」
  3. 上传图片(建议尺寸 1920×600px 或相近比例,横版)
  4. 设置跳转链接(可选)、排序、状态
  5. 保存后刷新首页即可看到轮播图
轮播图推荐使用同一比例(如 16:5、16:6)的图片,效果最佳。如果上传多张不同比例的图片,轮播区高度会按最高那张自动撑开。

API 配置

重要提醒:本主题为资讯类展示型主题,主题本身不依赖任何第三方 API,安装后即可直接使用。所有内容由后台文章、分类、广告、友情链接等模块统一管理。
只有在使用AI自动撰文来生成文章,才需要在逗号API网站有充足积分。(1分钱1篇/千字)

可以 充值积分 还可以 推广获积分

前端路由规则

<?php
function parse_rewrite_url($uri, $setting, $db, $prefix) {
    if ($uri === '/ubb' || $uri === '/ubb/') {
        return 'ubb_index';
    }
    if (preg_match('/^\/ubb\/([a-zA-Z0-9_\-]+)\/?$/', $uri, $matches)) {
        $_GET['slug'] = $matches[1];
        return 'ubb_page';
    }

    if ($uri === '/rs' || $uri === '/rs/') {
        return 'search_rs_index';
    }

    if (preg_match('/^\/rs\/(.+?)\/?$/', $uri, $matches)) {
        $keyword = urldecode($matches[1]);
        $keyword = trim($keyword);
        if ($keyword !== '') {
            $_GET['keyword'] = $keyword;
            return 'search';
        }
    }

    $article_prefix = preg_quote($setting['article_prefix'] ?? 'article-', '/');
    if (preg_match('/^\/' . $article_prefix . '([0-9a-zA-Z]+)\.html$/', $uri, $matches)) {
        $url_id = $matches[1];
        if ($setting['url_mode'] == 1) {
            $_GET['id'] = intval($url_id);
        } else {
            $field = ($setting['url_mode'] == 2) ? 'hash_id' : 'md5_id';
            $stmt = $db->prepare("SELECT id FROM {$prefix}article WHERE $field = ? LIMIT 1");
            if ($stmt) {
                $stmt->bind_param("s", $url_id);
                $stmt->execute();
                $res = $stmt->get_result();
                if ($res && $res->num_rows > 0) {
                    $row = $res->fetch_assoc();
                    $_GET['id'] = $row['id'];
                } else {
                    http_response_code(404);
                    require_once ROOT_PATH . '/set/404.php';
                    exit;
                }
                $stmt->close();
            } else {
                http_response_code(404);
                require_once ROOT_PATH . '/set/404.php';
                exit;
            }
        }
        return 'article';
    }
    
    $category_prefix = preg_quote($setting['category_prefix'] ?? 'category-', '/');
    if (preg_match('/^\/' . $category_prefix . '([0-9a-zA-Z]+)\.html$/', $uri, $matches)) {
        $url_id = $matches[1];
        $cat_url_mode = $setting['category_url_mode'] ?? 1;
        if ($cat_url_mode == 1) {
            $_GET['id'] = intval($url_id);
        } else {
            $field = ($cat_url_mode == 2) ? 'hash_id' : 'md5_id';
            $stmt = $db->prepare("SELECT id FROM {$prefix}category WHERE $field = ? LIMIT 1");
            if ($stmt) {
                $stmt->bind_param("s", $url_id);
                $stmt->execute();
                $res = $stmt->get_result();
                if ($res && $res->num_rows > 0) {
                    $row = $res->fetch_assoc();
                    $_GET['id'] = $row['id'];
                } else {
                    http_response_code(404);
                    require_once ROOT_PATH . '/set/404.php';
                    exit;
                }
                $stmt->close();
            } else {
                http_response_code(404);
                require_once ROOT_PATH . '/set/404.php';
                exit;
            }
        }
        return 'category';
    }
    
    if (preg_match('/^\/product\.html$/', $uri)) {
        return 'product_list';
    }
    
    $product_category_prefix = preg_quote($setting['product_category_prefix'] ?? 'product-category-', '/');
    if (preg_match('/^\/' . $product_category_prefix . '([0-9a-zA-Z]+)\.html$/', $uri, $matches)) {
        $url_id = $matches[1];
        $product_cat_url_mode = $setting['product_category_url_mode'] ?? 1;
        if ($product_cat_url_mode == 1) {
            $_GET['id'] = intval($url_id);
        } else {
            $field = ($product_cat_url_mode == 2) ? 'hash_id' : 'md5_id';
            $stmt = $db->prepare("SELECT id FROM {$prefix}product_category WHERE $field = ? LIMIT 1");
            if ($stmt) {
                $stmt->bind_param("s", $url_id);
                $stmt->execute();
                $res = $stmt->get_result();
                if ($res && $res->num_rows > 0) {
                    $row = $res->fetch_assoc();
                    $_GET['id'] = $row['id'];
                } else {
                    http_response_code(404);
                    require_once ROOT_PATH . '/set/404.php';
                    exit;
                }
                $stmt->close();
            } else {
                http_response_code(404);
                require_once ROOT_PATH . '/set/404.php';
                exit;
            }
        }
        return 'product_list';
    }
    
    $product_prefix = preg_quote($setting['product_prefix'] ?? 'product-', '/');
    if (preg_match('/^\/' . $product_prefix . '([0-9a-zA-Z]+)\.html$/', $uri, $matches)) {
        $url_id = $matches[1];
        $product_url_mode = $setting['product_url_mode'] ?? 1;
        if ($product_url_mode == 1) {
            $_GET['id'] = intval($url_id);
        } else {
            $field = ($product_url_mode == 2) ? 'hash_id' : 'md5_id';
            $stmt = $db->prepare("SELECT id FROM {$prefix}product WHERE $field = ? LIMIT 1");
            if ($stmt) {
                $stmt->bind_param("s", $url_id);
                $stmt->execute();
                $res = $stmt->get_result();
                if ($res && $res->num_rows > 0) {
                    $row = $res->fetch_assoc();
                    $_GET['id'] = $row['id'];
                } else {
                    http_response_code(404);
                    require_once ROOT_PATH . '/set/404.php';
                    exit;
                }
                $stmt->close();
            } else {
                http_response_code(404);
                require_once ROOT_PATH . '/set/404.php';
                exit;
            }
        }
        return 'product_detail';
    }
    
    if ($uri === '/list.html' || preg_match('/^\/list-([0-9]+)\.html$/', $uri, $matches)) {
        if (isset($matches[1])) $_GET['page'] = intval($matches[1]);
        return 'list';
    }
    
    if ($uri === '/' || $uri === '/index.php') {
        return 'index';
    }
    
    return '404';
}

function route_dispatch($action, $db, $prefix, $setting, $template_path) {
    if ($action === '404') {
        http_response_code(404);
        require_once ROOT_PATH . 'set/404.php';
        exit;
    }

    if ($action === 'ubb_index') {
        $seo_row = $db->query("SELECT * FROM {$prefix}seo WHERE page_name = 'ubb_index' LIMIT 1")->fetch_assoc();
        $site_name = $setting['site_name'] ?? '逗号CMS';
        if ($seo_row) {
            $seo = [
                'title' => str_replace('{site_name}', $site_name, $seo_row['title'] ?: ('留言本 - ' . $site_name)),
                'keywords' => str_replace('{site_name}', $site_name, $seo_row['keywords']),
                'description' => str_replace('{site_name}', $site_name, $seo_row['description']),
            ];
        } else {
            $seo = [
                'title' => '留言本 - ' . $site_name,
                'keywords' => '留言本,在线留言,反馈',
                'description' => '欢迎使用在线留言本,选择您想要留言的页面'
            ];
        }
        include $template_path . 'header.php';
        require ROOT_PATH . 'set/ubb/index.php';
        include $template_path . 'footer.php';
        return true;
    }

    if ($action === 'ubb_page') {
        $slug = isset($_GET['slug']) ? trim($_GET['slug']) : '';
        $page_info_row = $db->query("SELECT * FROM {$prefix}ubb_pages WHERE slug = '" . $db->real_escape_string($slug) . "' AND status = 1 LIMIT 1")->fetch_assoc();
        $site_name = $setting['site_name'] ?? '逗号CMS';
        if ($page_info_row) {
            $seo_row = $db->query("SELECT * FROM {$prefix}seo WHERE page_name = 'ubb_page' LIMIT 1")->fetch_assoc();
            $replace_map = [
                '{page_name}' => $page_info_row['name'],
                '{page_description}' => $page_info_row['description'] ?: $page_info_row['name'],
                '{site_name}' => $site_name,
            ];
            if ($seo_row) {
                $seo = [
                    'title' => str_replace(array_keys($replace_map), array_values($replace_map), $seo_row['title'] ?: ($page_info_row['name'] . ' - ' . $site_name)),
                    'keywords' => str_replace(array_keys($replace_map), array_values($replace_map), $seo_row['keywords']),
                    'description' => str_replace(array_keys($replace_map), array_values($replace_map), $seo_row['description']),
                ];
            } else {
                $seo = [
                    'title' => $page_info_row['name'] . ' - ' . $site_name,
                    'keywords' => $page_info_row['name'],
                    'description' => $page_info_row['description'] ?: $page_info_row['name']
                ];
            }
        } else {
            $seo = [
                'title' => '留言页 - ' . $site_name,
                'keywords' => '',
                'description' => ''
            ];
        }
        include $template_path . 'header.php';
        require ROOT_PATH . 'set/ubb/page.php';
        include $template_path . 'footer.php';
        return true;
    }

    if ($action === 'search_rs_index') {
        $site_name = $setting['site_name'] ?? '逗号CMS';
        $seo_row = $db->query("SELECT * FROM {$prefix}seo WHERE page_name = 'search_rs_index' LIMIT 1")->fetch_assoc();
        if ($seo_row) {
            $seo = [
                'title' => str_replace('{site_name}', $site_name, $seo_row['title'] ?: ('热搜标签 - ' . $site_name)),
                'keywords' => str_replace('{site_name}', $site_name, $seo_row['keywords']),
                'description' => str_replace('{site_name}', $site_name, $seo_row['description']),
            ];
        } else {
            $seo = [
                'title' => '热搜标签 - ' . $site_name,
                'keywords' => '热搜,标签,热门搜索',
                'description' => '网站热搜标签聚合页'
            ];
        }
        include $template_path . 'header.php';
        include $template_path . 'search_rs.php';
        include $template_path . 'footer.php';
        return true;
    }

    if ($action === 'search') {
        $_GET['action'] = 'search';
        $keyword = isset($_GET['keyword']) ? trim($_GET['keyword']) : '';
        $keyword_display = $keyword;
        if (!empty($keyword)) {
            if (!check_sensitive_words($keyword)) {
                http_response_code(404);
                require_once ROOT_PATH . 'set/404.php';
                exit;
            }
            record_hot_search($keyword);
            $keyword_escaped = str_replace(['%', '_'], ['\\%', '\\_'], $keyword);
            save_search_keyword($keyword_escaped);

            $keywords = split_search_keywords($keyword);
            $page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
            $page_size = 20;
            $search_result = search_articles_by_keywords($keywords, $page, $page_size);
            $articles = $search_result['articles'];
            $total = $search_result['total'];
            $base_url = "/rs/" . rawurlencode($keyword) . "?";
            $pagination = pagination($total, $page_size, $page, $base_url);
        } else {
            $articles = [];
            $total = 0;
            $pagination = '';
            $search_result = ['keywords' => []];
        }
        $seo = get_seo('search', ['keyword' => $keyword_display]);
        include $template_path . 'header.php';
        include $template_path . 'category.php';
        include $template_path . 'footer.php';
        return true;
    }
    
    if ($action === 'list') {
        $page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
        $page_size = 20;
        
        $total = get_article_count();
        $offset = ($page - 1) * $page_size;
        $articles = get_articles('', "$offset, $page_size");
        $base_url = "/list.html?";
        $pagination = pagination($total, $page_size, $page, $base_url);
        
        $seo = get_seo('category', ['category_name' => '全部文章']);
        
        include $template_path . 'header.php';
        include $template_path . 'category.php';
        include $template_path . 'footer.php';
        return true;
    }
    
    if ($action === 'category') {
        $category_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
        $page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
        $page_size = 20;
        
        $category_name = '';
        $categories = get_categories();
        foreach ($categories as $cat) {
            if ($cat['id'] == $category_id) {
                $category_name = $cat['name'];
                break;
            }
        }
        if (!$category_name) {
            http_response_code(404);
            require_once ROOT_PATH . '/set/404.php';
            exit;
        }
        
        $seo = get_seo('category', ['category_name' => $category_name]);
        
        $where = "category_id = $category_id";
        $total = get_article_count($where);
        $offset = ($page - 1) * $page_size;
        $articles = get_articles($where, "$offset, $page_size");
        $base_url = "/" . ($setting['category_prefix'] ?? 'category-') . build_url_id('category', $category_id) . ".html?";
        $pagination = pagination($total, $page_size, $page, $base_url);
        
        include $template_path . 'header.php';
        include $template_path . 'category.php';
        include $template_path . 'footer.php';
        return true;
    }
    
    if ($action === 'article') {
        $id = isset($_GET['id']) ? intval($_GET['id']) : 0;
        $article = get_article($id);
        if (!$article) {
            http_response_code(404);
            require_once ROOT_PATH . '/set/404.php';
            exit;
        }
        update_views($id);
        
        $category_name = '';
        $categories = get_categories();
        foreach ($categories as $cat) {
            if ($cat['id'] == $article['category_id']) {
                $category_name = $cat['name'];
                break;
            }
        }
        
        $seo = get_seo('article', [
            'article_title' => $article['title'],
            'article_description' => $article['description'] ?: mb_substr(strip_tags($article['content']), 0, 150),
            'category_name' => $category_name
        ]);
        
        include $template_path . 'header.php';
        include $template_path . 'article.php';
        include $template_path . 'footer.php';
        return true;
    }
    
    if ($action === 'product_list') {
        $category_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
        $page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
        $page_size = 12;
        
        $category_name = '全部产品';
        if ($category_id > 0) {
            $cats = $db->query("SELECT * FROM {$prefix}product_category ORDER BY sort ASC");
            while ($cat = $cats->fetch_assoc()) {
                if ($cat['id'] == $category_id) {
                    $category_name = $cat['name'];
                    break;
                }
            }
        }
        
        $seo = get_seo('product_list', ['category_name' => $category_name]);
        
        if ($category_id > 0) {
            $where = "WHERE category_id = $category_id";
            $total = $db->query("SELECT COUNT(*) as t FROM {$prefix}product $where")->fetch_assoc()['t'];
        } else {
            $where = '';
            $total = $db->query("SELECT COUNT(*) as t FROM {$prefix}product")->fetch_assoc()['t'];
        }
        
        $offset = ($page - 1) * $page_size;
        $products = $db->query("SELECT * FROM {$prefix}product $where ORDER BY id DESC LIMIT $offset, $page_size");
        $product_cats = $db->query("SELECT * FROM {$prefix}product_category ORDER BY sort ASC");
        
        include $template_path . 'header.php';
        include $template_path . 'product_list.php';
        include $template_path . 'footer.php';
        return true;
    }
    
    if ($action === 'product_detail') {
        $id = isset($_GET['id']) ? intval($_GET['id']) : 0;
        $product = $db->query("SELECT p.*, c.name as category_name FROM {$prefix}product p LEFT JOIN {$prefix}product_category c ON p.category_id = c.id WHERE p.id = $id")->fetch_assoc();
        if (!$product) {
            http_response_code(404);
            require_once ROOT_PATH . '/set/404.php';
            exit;
        }
        $db->query("UPDATE {$prefix}product SET views = views + 1 WHERE id = $id");
        
        $gallery = json_decode($product['gallery'], true);
        if (!is_array($gallery)) $gallery = [];
        
        $seo = get_seo('product_detail', [
            'product_title' => $product['title'],
            'product_description' => $product['description'],
            'category_name' => $product['category_name'] ?? ''
        ]);
        
        include $template_path . 'header.php';
        include $template_path . 'product_detail.php';
        include $template_path . 'footer.php';
        return true;
    }
    
    if ($action === 'index') {
        $seo = get_seo('index');
        $ads = get_ads(5);
        $recommend_articles = get_articles('is_recommend = 1', $seo['recommend_count']);
        $latest_articles = get_articles('', $seo['latest_count']);
        $latest_searches = get_latest_search(5);
        
        include $template_path . 'header.php';
        include $template_path . 'index.php';
        include $template_path . 'footer.php';
        return true;
    }
    
    return false;
}

更新日志

V1.1 适配CMSV7.4版本路由兼容性 2026-10-24
1、适配CMSV7.4版本路由兼容性(未升级到CMS v7.4版本无需升级)2、升级后可到文章管理--分类管理处设置分类英文名(伪静态设置处增加分类英文名标签)

常见问题

主题截图 1 / 1