PbootCMS作为一款国内主流的开源CMS系统,,本文带你全面掌握内容详情页标签。
在进行内容详情页标签的二次开发前,需要熟悉 PbootCMS 的基本结构。PbootCMS 采用 MVC 架构,模板文件存放在 /template/
目录下,核心控制器位于 /apps/home/controller/
目录。详情页对应的模板通常是 content.html
。
核心标签解析流程涉及 /apps/home/controller/ParserController.php
文件,系统会依次解析各类标签。在进行任何修改前,务必备份相关文件。
对于简单的扩展需求,如为文章增加“文章来源”、“阅读时长”等属性,最便捷的方式是使用自定义字段。
ext_source
(文章来源),字段类型选择“单行文本”。在 content.html
模板中,使用 {content:ext_source}
即可调用该字段。
<p>文章来源:{content:ext_source}</p>
所有自定义字段均通过 {content:ext_*}
的格式调用[^文档内容]。
如果需要改变系统内置标签的默认输出结构,例如为上一篇、下一篇链接添加特定的 HTML 包装,则需要修改核心控制器。
目标:将默认的 <a>
标签链接用 <li>
标签包裹。
修改文件:/apps/home/controller/ParserController.php
。
precontent
方法(约第3706行),该方法负责解析 {content:precontent}
。nextcontent
方法(约第3754行),该方法负责解析 {content:nextcontent}
。 修改代码:
// 修改 precontent 方法中的输出部分
public function precontent($content) {
$pre = $this->getPrevContent($content);
// 原始代码可能是:$str = '<a href="' . $pre['url'] . '">' . $pre['title'] . '</a>';
// 修改为:
if ($pre) { $str = '<li class="prev-article"><a href="' . $pre['url'] . '">' . $pre['title'] . '</a></li>'; } else { $str = '<li>已经是第一篇了</li>';
// 自定义无内容时的提示 } return $str; }
// 同理修改 nextcontent 方法 public function nextcontent($content) { $next = $this->getNextContent($content); if ($next) { $str = '<li class="next-article"><a href="' . $next['url'] . '">' . $next['title'] . '</a></li>'; } else { $str = '<li>已经是最后一篇了</li>'; } return $str; } [1](@ref)
修改后,模板中调用 {content:precontent} 和 {content:nextcontent} 时,输出的 HTML 结构就会包含 <li> 标签,便于前端样式的控制。
当系统内置标签无法满足复杂业务逻辑时(如根据 Tag 相关度推荐内容),需要开发自定义标签。
创建文件:在 /apps/home/controller/
目录下创建 ExtLabelController.php
。
<?php
namespace app\home\controller;
use core\BasicController;
class ExtLabelController extends BasicController
{
/**
* 自定义标签入口方法
*/
public function run($content)
{
// 解析内容相关性标签,例如 {pboot:related}
$content = $this->parserRelatedLabel($content);
// 可以继续添加其他自定义标签的解析方法
return $content;
}
/**
* 解析相关文章标签
* 格式:{pboot:related num='5'} <a href="[related:link]">[related:title]</a> {/pboot:related}
*/
private function parserRelatedLabel($content)
{
$pattern = '/\{pboot:related(\s+[^}]+)?\}(.*?)\{\/pboot:related\}/is';
if (preg_match_all($pattern, $content, $matches)) {
$count = count($matches;
for ($i = 0; $i < $count; $i++) {
// 1. 获取标签参数,如数量 num
$params = $this->parserParam($matches[$i]);
$num = isset($params['num']) ? $params['num'] : 5;
// 2. 获取内部模板(即标签之间的HTML结构)
$innerHtml = $matches[$i];
// 3. 核心业务逻辑:根据当前文章的Tag或分类获取相关文章
$relatedData = $this->getRelatedContents($num);
// 4. 组合数据与模板
$parsedHtml = '';
foreach ($relatedData as $item) {
$itemHtml = $innerHtml;
// 替换内部变量 [related:link] -> $item['link'], [related:title] -> $item['title']
$itemHtml = str_replace('[related:link]', $item['link'], $itemHtml);
$itemHtml = str_replace('[related:title]', $item['title'], $itemHtml);
$parsedHtml .= $itemHtml;
}
// 5. 将模板中的原始标签块替换为解析后的HTML
$content = str_replace($matches[$i], $parsedHtml, $content);
}
}
return $content;
}
/**
* 获取相关文章数据(示例逻辑:基于当前文章的Tag匹配)
*/
private function getRelatedContents($num)
{
// 获取当前内容ID
$currentContentId = get('content.id'); // 假设能通过某种方式获取当前文章ID
$currentTags = $this->model->getContentTags($currentContentId); // 获取当前文章Tag
// 基于Tag进行匹配查询的逻辑,这里简化表示
// 实际开发中需要编写具体的数据库查询
$relatedList = $this->model->getListByTags($currentTags, $num, $currentContentId);
return $relatedList;
}
/**
* 解析标签参数(辅助方法)
*/
private function parserParam($str)
{
// 解析出标签中的参数,如 num='5'
$params = [];
// ... 参数解析逻辑 ...
return $params;
}
}
修改文件:需要修改系统的主解析流程文件,通常是 /apps/home/controller/IndexController.php
(或类似的入口控制器),找到解析模板内容的方法(如 parser
方法)。
在该方法中合适的位置(例如,在解析其他系统标签之后,解析IF语句等逻辑标签之前)加入以下代码:
// 在 parser 方法中,位于其他标签解析之后
$content = $this->parserCompanyLabel($content); // 公司标签
$content = $this->parserNavLabel($content); // 导航标签
// ... 其他系统标签解析 ...
// === 加入:解析自定义扩展标签 ===
if (config('ext_label')) { // 可以从配置判断是否开启
if (file_exists('/home/controller/ExtLabelController.php')) {
if (class_exists('app\home\controller\ExtLabelController')) {
$extlabel = new ExtLabelController();
$content = $extlabel->run($content);
}
}
}
// ... 后续继续系统原有的解析,如分页、IF语句等 ...
$content = $this->parserPageLabel($content);
在 content.html
中,你就可以使用自己定义的 {pboot:related}
标签了:
<div class="related-articles">
<h3>相关推荐</h3>
{pboot:related num='5'}
<a href="[related:link]" class="related-item">[related:title]</a>
{/pboot:related}
</div>
PbootCMS 老版本默认未提供 Tag 功能,但可通过二次开发实现强大的 Tag 系统。
tag
的“单行文本”字段,输入时用逗分隔多个 Tag。content.html
中,使用以下代码调用并遍历 Tag: <div class="content-tags"> <span>关键词:</span> {content:tags split=','} <a href="/tag/?tag={pboot:tag}" class="tag">{pboot:tag}</a> {/content:tags} </div>
这里的 split=','
参数指定了 Tag 之间的分隔符为逗号。{pboot:tag}
在循环中代表每个 Tag 项。taglist.html
。taglist.html
中,使用 {pboot:tag}
循环所有 Tag 并显示其关联文章数量。 <ul> {pboot:tag} <li><a href="[tag:link]">[tag:name] ({tag:count})</a></li> {/pboot:tag} </ul>
taglist.html
作为模板,并设置访问路径。ParserController.php
等核心文件前务必备份。ParserController.php
中,各类标签的解析有固定顺序,自定义标签的注入点需谨慎选择,避免破坏原有逻辑。原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。