1.1 基本调用语法
PbootCMS提供了三种主要的tags标签调用方式:
<!-- 1、调用指定栏目下的内容tags -->
{pboot:tags scode=5,7 num=10}
<a href='[tags:link]'>[tags:text]</a>
{/pboot:tags}
<!-- 2、调用指定内容的tags -->
{pboot:tags id=123}
<span class="tag">[tags:text]</span>
{/pboot:tags}
<!-- 3、使用tags显示相似内容列表 -->
{pboot:list scode=* tags='科技,互联网'}
<a href="[list:link]">[list:title]</a>
{/pboot:list}
在tags标签中,我们可以使用以下变量:
变量 | 说明 | 示例 |
---|---|---|
[tags:n] | 序号从0开始 | 0, 1, 2... |
[tags:i] | 序号从1开始 | 1, 2, 3... |
[tags:link] | 链接地址 | /tag/科技.html |
[tags:text] | tags名称 | 科技、互联网 |
在实际项目中,基础的tags功能可能无法满足个性化需求。下面我将实现一个智能相关内容推荐系统,根据内容标签匹配度自动推荐最相关的内容。
传统tags关联仅简单匹配包含的标签,我们希望通过二次开发实现以下增强功能:
在 /apps/home/controller/
目录下新建 TagsController.php
文件:
<?php
/**
* PbootCMS Tags二次开发控制器
* 实现智能相关内容推荐功能
* 文件位置:/apps/home/controller/TagsController.php
*/
class TagsController extends Controller
{
/**
* 获取智能相关内容
* @param int $contentId 当前内容ID
* @param int $num 需要返回的数量
* @return array 相关内容列表
*/
public function getSmartRelatedContents($contentId, $num = 5)
{
if (!$contentId) {
return [];
}
// 获取当前内容的标签
$currentTags = $this->getContentTags($contentId);
if (empty($currentTags)) {
return [];
}
// 获取所有内容并计算相关度
$allContents = $this->getAllContents();
$scoredContents = [];
foreach ($allContents as $content) {
if ($content['id'] == $contentId) {
continue; // 排除当前内容
}
$score = $this->calculateRelevanceScore($content, $currentTags);
if ($score > 0) {
$scoredContents[] = [
'content' => $content,
'score' => $score
];
}
}
// 按分数排序并返回前$num个结果
usort($scoredContents, function($a, $b) {
return $b['score'] - $a['score'];
});
return array_slice($scoredContents, 0, $num);
}
/**
* 获取内容标签
* @param int $contentId 内容ID
* @return array 标签数组
*/
private function getContentTags($contentId)
{
$model = new Model();
$result = $model->table('ay_content_tags')
->field('tag_text')
->where("content_id='$contentId'")
->select();
$tags = [];
foreach ($result as $item) {
$tags[] = $item['tag_text'];
}
return $tags;
}
/**
* 获取所有内容(可缓存优化性能)
* @return array 内容数组
*/
private function getAllContents()
{
$model = new Model();
return $model->table('ay_content')
->field('id,title,content,tags,date,visits,scode')
->where('status=1')
->select();
}
/**
* 计算内容相关度分数
* @param array $content 待比较内容
* @param array $currentTags 当前内容标签
* @return float 相关度分数
*/
private function calculateRelevanceScore($content, $currentTags)
{
$score = 0;
// 1. 标签匹配度(权重最高:60%)
$contentTags = explode(',', $content['tags']);
$matchedTags = array_intersect($contentTags, $currentTags);
$tagScore = (count($matchedTags) / count($currentTags)) * 60;
$score += $tagScore;
// 2. 时间因子(权重:20%)
$daysAgo = floor((time() - strtotime($content['date'])) / (60 * 60 * 24));
$timeScore = max(0, 20 - ($daysAgo * 0.1)); // 每天衰减0.1分
$score += $timeScore;
// 3. 热度因子(权重:20%)
$visitScore = min(20, log($content['visits'] + 1) * 2);
$score += $visitScore;
return round($score, 2);
}
}
在 /template/default/
目录下的模板文件中,我们可以使用扩展的tags功能。以文章详情页为例,在 detail.html
中添加:
<!-- 智能相关内容推荐 -->
<div class="smart-related">
<h3>相关推荐</h3>
<div class="related-list">
{php $relatedContents = TagsController::getSmartRelatedContents({content:id}, 5); }
{foreach $relatedContents as $index => $item}
<div class="related-item">
<span class="order">{$index + 1}</span>
<a href="{content:link id=$item.content.id}" title="相关度:{$item.score}分">
{$item.content.title}
</a>
<span class="visits">浏览:{$item.content.visits}</span>
</div>
{/foreach}
</div>
</div>
<style>
.smart-related {
margin: 20px 0;
padding: 15px;
border: 1px solid #eaeaea;
}
.related-item {
padding: 8px 0;
border-bottom: 1px dashed #f0f0f0;
}
.related-item .order {
display: inline-block;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
background: #4CAF50;
color: white;
border-radius: 50%;
margin-right: 10px;
}
.related-item .visits {
float: right;
color: #999;
font-size: 12px;
}
</style>
进一步扩展tags功能,创建可视化标签云,根据标签使用频率和热度生成不同样式的标签云。
在 /apps/home/controller/
目录下扩展 TagsController.php
:
<?php
/**
* 标签云生成功能
*/
class TagsController extends Controller
{
/**
* 生成标签云数据
* @param int $maxTags 最大标签数量
* @param int $minFont 最小字体大小(px)
* @param int $maxFont 最大字体大小(px)
* @return array 标签云数据
*/
public function generateTagCloud($maxTags = 50, $minFont = 12, $maxFont = 36)
{
$model = new Model();
// 获取标签使用频率
$sql = "SELECT tag_text, COUNT(*) as usage_count
FROM ay_content_tags
GROUP BY tag_text
ORDER BY usage_count DESC
LIMIT $maxTags";
$tags = $model->query($sql);
if (empty($tags)) {
return [];
}
// 计算字体大小
$maxCount = max(array_column($tags, 'usage_count'));
$minCount = min(array_column($tags, 'usage_count'));
$tagCloud = [];
foreach ($tags as $tag) {
$fontSize = $this->calculateFontSize(
$tag['usage_count'],
$minCount,
$maxCount,
$minFont,
$maxFont
);
$tagCloud[] = [
'text' => $tag['tag_text'],
'count' => $tag['usage_count'],
'size' => $fontSize,
'link' => $this->getTagLink($tag['tag_text'])
];
}
// 随机排序以实现云效果
shuffle($tagCloud);
return $tagCloud;
}
/**
* 根据使用频率计算字体大小
*/
private function calculateFontSize($count, $minCount, $maxCount, $minFont, $maxFont)
{
if ($maxCount == $minCount) {
return ($minFont + $maxFont) / 2;
}
$fontSize = $minFont + (($count - $minCount) * ($maxFont - $minFont)) / ($maxCount - $minCount);
return round($fontSize);
}
/**
* 获取标签链接
*/
private function getTagLink($tagText)
{
// 使用PbootCMS路由生成标签页链接
return url('/tags', ['text' => urlencode($tagText)]);
}
}
在需要显示标签云的页面模板中添加:
<!-- 标签云显示 -->
<div class="tag-cloud">
{php $tagCloud = TagsController::generateTagCloud(50, 12, 36); }
{foreach $tagCloud as $tag}
<a href="{$tag.link}" class="tag-item" style="font-size: {$tag.size}px;"
title="使用次数:{$tag.count}">
{$tag.text}
</a>
{/foreach}
</div>
<style>
.tag-cloud {
text-align: center;
line-height: 2.5;
padding: 20px;
}
.tag-item {
margin: 0 8px 8px 0;
padding: 4px 12px;
display: inline-block;
color: #333;
text-decoration: none;
border-radius: 4px;
background: #f5f5f5;
transition: all 0.3s ease;
}
.tag-item:hover {
background: #4CAF50;
color: white;
transform: translateY(-2px);
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
}
</style>
对于tags二次开发功能,性能优化尤为重要。以下是几种优化方案:
在 /apps/common/
目录下创建 CacheUtil.php
:
<?php
/**
* 缓存工具类
* 文件位置:/apps/common/CacheUtil.php
*/
class CacheUtil
{
/**
* 获取缓存数据
*/
public static function getCache($key, $expire = 3600, $callback = null)
{
$cacheFile = self::getCacheFile($key);
// 缓存存在且未过期
if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < $expire) {
return unserialize(file_get_contents($cacheFile));
}
// 生成新缓存
if ($callback && is_callable($callback)) {
$data = call_user_func($callback);
self::setCache($key, $data);
return $data;
}
return null;
}
/**
* 设置缓存数据
*/
public static function setCache($key, $data)
{
$cacheFile = self::getCacheFile($key);
file_put_contents($cacheFile, serialize($data));
}
/**
* 获取缓存文件路径
*/
private static function getCacheFile($key)
{
$cacheDir = ROOT_PATH . '/runtime/cache/';
if (!is_dir($cacheDir)) {
mkdir($cacheDir, 0755, true);
}
return $cacheDir . md5($key) . '.cache';
}
}
使用缓存优化TagsController:
// 在TagsController中修改相关方法
public function getSmartRelatedContents($contentId, $num = 5)
{
$cacheKey = "related_contents_{$contentId}_{$num}";
return CacheUtil::getCache($cacheKey, 1800, function() use ($contentId, $num) {
// 原有的计算逻辑...
return $scoredContents;
});
}
通过本次二次开发,我们显著增强了PbootCMS的tags标签功能,实现了智能相关内容推荐和可视化标签云两大核心功能。关键实现点包括:
/apps/home/controller/TagsController.php
/template/default/
下的模板文件中使用扩展功能原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。