说明
最近开发完了Freewind主题
,把在开发过程中用到的一些Typecho
本身不支持但又比较常用的功能总结一下分享给大家
效果
废话先不说,直接看效果
想法
Typecho
本身是没有点赞的功能,甚至没有这个字段,开始是想用定义意字段解决来着,后来想着直接就往表里加入新字段,这样还省得多表查询
想法是这样的
- 在
table.contents
表中加入新字段 - 用
Cookie
记录用户是否点过赞
我们先做一个约定,在Cookie
中的extend_contents_support
值中存已点赞的文章,用,
隔开
规划是两个方法
- 方法1负责获取点赞数,除了获取之外在第一次调用该方法时会向
table.contents
表中加入support
字段用于记录点赞数 - 方法2用于点赞功能
编码
思路有了,我们就可以开始coding了
获取点赞数
- 创建方法签名如
function get_post_support($cid)
,参数为文章cid
,返回值我们约定如下
{
"icon": "图标" , //图标,这里根据自己需要来,我这里未点赞是一个空心,已点赞是一个实心
"count": "点赞数",
"text":"是否点赞",//也是根据自己需要来
}
- 在方法中用如下代码获取数据库对象
$db = Typecho_Db::get();
$prefix = $db->getPrefix();
- 判断
support
字段是否存在,若不存在则创建并且本次返回0
if (!array_key_exists('support', $db->fetchRow($db->select()->from('table.contents')))) {
// 加入support字段
$db->query('ALTER TABLE `' . $prefix . 'contents` ADD `support` INT(10) DEFAULT 0;');
//返回点赞数为0
return [
'icon' => 'icon-xin', //空心标签,代表未点过赞
'count' => 0, //第一次进入,没有点赞数,为0
'text' => '点赞' //列表页面显示的文字
];
}
- 查询数据库获取点赞数,从
Cookie
获取已点赞文章,并于,
切分为数组
$row = $db->fetchRow($db->select('support')->from('table.contents')->where('cid = ?', $cid));
//从cookie中获取已点赞的文章cid
$support = Typecho_Cookie::get('extend_contents_support');
if (empty($support)) {
//cookie中已点赞为空则创建新数组
$support = array();
} else {
//用,切分获取所有点赞的文章cid
$support = explode(',', $support);
}
- 判断是否已点赞并返回
if (!in_array($cid, $support)) {
return [
'icon' => 'icon-xin',
'count' => $row['support'],
'text' => '点赞'
];
} else {
return [
'icon' => 'icon-theheart-fill', //实心图标
'count' => $row['support'],
'text' => '已赞'
];
}
- 全部代码
function get_post_support($cid)
{
$db = Typecho_Db::get();
$prefix = $db->getPrefix();
if (!array_key_exists('support', $db->fetchRow($db->select()->from('table.contents')))) {
$db->query('ALTER TABLE `' . $prefix . 'contents` ADD `support` INT(10) DEFAULT 0;');
return [
'icon' => 'icon-xin',
'count' => 0,
'text' => '点赞'
];
}
$row = $db->fetchRow($db->select('support')->from('table.contents')->where('cid = ?', $cid));
$support = Typecho_Cookie::get('extend_contents_support');
if (empty($support)) {
$support = array();
} else {
$support = explode(',', $support);
}
if (!in_array($cid, $support)) {
return [
'icon' => 'icon-xin',
'count' => $row['support'],
'text' => '点赞'
];
} else {
return [
'icon' => 'icon-theheart-fill',
'count' => $row['support'],
'text' => '已赞'
];
}
}
点赞功能
- 创建方法签名如
function support_add($cid)
,参数为文章cid
,如果未点赞,返回当前点赞数+1,若已点赞,返回false
- 获取数据库对象并从
Cookie
中获取已点赞的文章并于,
切分为数组
//这些注释前面有,这里就不写了
$db = Typecho_Db::get();
$row = $db->fetchRow($db->select('support')->from('table.contents')->where('cid = ?', $cid));
$support = Typecho_Cookie::get('extend_contents_support');
if (empty($support)) {
$support = array();
} else {
$support = explode(',', $support);
}
- 判断是否点过赞,若没有更新数据库中的点赞数+1
if (!in_array($cid, $support)) {
$db->query($db->update('table.contents')->rows(array('support' => (int)$row['support'] + 1))->where('cid = ?', $cid));
array_push($support, $cid);
$support = implode(',', $support);
Typecho_Cookie::set('extend_contents_support', $support);
return $row['support'] + 1;
} else {
return false;
}
- 所有代码
function support_add($cid)
{
//获取数据库对象并从Cookie中获取已点赞的文章并于,切分为数组
$db = Typecho_Db::get();
$row = $db->fetchRow($db->select('support')->from('table.contents')->where('cid = ?', $cid));
$support = Typecho_Cookie::get('extend_contents_support');
if (empty($support)) {
$support = array();
} else {
$support = explode(',', $support);
}
//判断文章是否已经点过赞
if (!in_array($cid, $support)) {
//未点赞,更新数据库
$db->query($db->update('table.contents')->rows(array('support' => (int)$row['support'] + 1))->where('cid = ?', $cid));
//将文章cid加入cookie
array_push($support, $cid);
$support = implode(',', $support);
Typecho_Cookie::set('extend_contents_support', $support);
//返回点赞数
return $row['support'] + 1;
} else {
//已点赞,不进行任何操作,直接返回
return false;
}
}
页面调用
- 显示点赞数
<!-- 获取我们刚刚约定的返回值,包含图标,点赞数,显示文字 -->
<?php $suport = get_post_support($this->cid) ?>
<!-- 这里就是刚刚的图标 -->
<i class="iconfont <?php echo $suport['icon'] ?>">
<!--
data-cid 为要点赞的文章cid,我们在点击a标签时会发送一个ajax请求
href 点击a标签后不跳转则写法如下
-->
<a class="post-suport"
data-cid="<?php echo $this->cid ?>"
href="javascript:void (0)">
<!--显示文字为(点赞娄)点赞/已赞-->
<?php echo '('.$suport['count'] .')'. $suport['text'] ?>
</a>
</i>
- 显示效果图如下
Ajax点赞
我们都知道Typecho
在渲染主题的时候会先执行function themeInit(Widget_Archive $archive)
方法,我们在该方法里判断是否为点赞操作
- 判断点赞操作
//点赞
if ($archive->request->isPost() && $archive->request->is('action=support')) {
//点赞方法
$res = support_add($archive->request->get('cid'));
//返回json给前端
$json = [
'success' => $res ? true : false,
'count' => $res
];
ob_clean();
echo json_encode($json);
exit();
}
- 引入
jquery
与layer
库,这个根据自身需要引入
这里用了jquery
与layer
,点赞后的事件请自行根据需求来编写
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/layer/3.1.1/layer.min.js"></script>
- 为刚刚的
a
标签加入点击事件
$('.post-suport').on('click', function () {
//我们刚刚在a标签上设置了data-cid=文章cid的属性,这里直接取出来
let cid = $(this).data('cid');
$.ajax({
url: `/?action=support`,
type: 'POST',
data: {
cid: cid
},
dataType: 'json',
success: res => {
if (res.success) {
//点赞成功,更新页面的点赞数并更改文字与图标
$(this).parent().removeClass('icon-xin').addClass('icon-theheart-fill')
$(this).text('(' + res.count + ')' + '已赞')
} else {
layer.msg('该文章您已点过赞啦', {icon: 2})
}
}
})
})
结束
我们就可以实现一开始演示的效果啦
核心代码我已经罗列出来了,大家可以根据自已需要来做修改
当然,freewind
主题已经支持该工能啦
打瞌睡 游客 2022-05-13 14:55 回复
为什么我的点赞不能用啊,应该是缺少这个代码,不过在哪里加入代码啊,可不可以给个具体一点的教程,点赞显示文章内容不能为空
打瞌睡 游客 2022-05-13 10:32 回复
点赞显示文章内容不能为空是什么情况?
1585364631 游客 2022-03-03 17:26 回复
点赞显示文章内容不能为空
1585364631 游客 2022-03-03 17:12 回复
请问一下是直接把全部代码加在function.php文件中吗
江河三千里 游客 2022-01-05 00:30 回复
请问这个php文件中的function应该加在什么地方啊
MR丶冷文 管理员 2022-01-05 10:08 回复
@江河三千里
function.php