Typecho 主题开发 - 点赞功能
Typecho 默认是没有提供点赞相关的 API 的,点赞功能只能自己开发,点赞也需要涉及到数据库操作。这里就以 我的博客主题 点赞功能为例,简单写一下点赞功能的开发。
编写函数
Typecho 提供了一个 functions.php
,可以用来定义函数,数据库相关的操作就放在 functions.php
中。
下面编写两个函数,agreeNum
函数用来获取点赞数量,agree
函数用来点赞。
agreeNum
函数:
function agreeNum($cid) {
$db = Typecho_Db::get();
$prefix = $db->getPrefix();
// 判断点赞数量字段是否存在
if (!array_key_exists('agree', $db->fetchRow($db->select()->from('table.contents')))) {
// 在文章表中创建一个字段用来存储点赞数量
$db->query('ALTER TABLE `' . $prefix . 'contents` ADD `agree` INT(10) NOT NULL DEFAULT 0;');
}
// 查询出点赞数量
$agree = $db->fetchRow($db->select('table.contents.agree')->from('table.contents')->where('cid = ?', $cid));
// 获取记录点赞的 Cookie
$AgreeRecording = Typecho_Cookie::get('typechoAgreeRecording');
// 判断记录点赞的 Cookie 是否存在
if (empty($AgreeRecording)) {
// 如果不存在就写入 Cookie
Typecho_Cookie::set('typechoAgreeRecording', json_encode(array(0)));
}
// 返回
return array(
// 点赞数量
'agree' => $agree['agree'],
// 文章是否点赞过
'recording' => in_array($cid, json_decode(Typecho_Cookie::get('typechoAgreeRecording')))?true:false
);
}
上面的函数很简单,下面是说明:
- 判断存储点赞数量的字段是否存在。
- 如果点赞数的字段不存在就创建。
- 查询出点赞数量。
- 获取点赞记录的 Cookie。
- 判断文章是否点赞过。
- 返回点赞数量和点赞记录。
上面的 agreeNum
函数调用的时候需要传入一个 cid
,cid
就是 Typecho 的文章 ID。
agree
函数:
function agree($cid) {
$db = Typecho_Db::get();
// 根据文章的 `cid` 查询出点赞数量
$agree = $db->fetchRow($db->select('table.contents.agree')->from('table.contents')->where('cid = ?', $cid));
// 获取点赞记录的 Cookie
$agreeRecording = Typecho_Cookie::get('typechoAgreeRecording');
// 判断 Cookie 是否存在
if (empty($agreeRecording)) {
// 如果 cookie 不存在就创建 cookie
Typecho_Cookie::set('typechoAgreeRecording', json_encode(array($cid)));
}else {
// 把 Cookie 的 JSON 字符串转换为 PHP 对象
$agreeRecording = json_decode($agreeRecording);
// 判断文章是否点赞过
if (in_array($cid, $agreeRecording)) {
// 如果当前文章的 cid 在 cookie 中就返回文章的赞数,不再往下执行
return $agree['agree'];
}
// 添加点赞文章的 cid
array_push($agreeRecording, $cid);
// 保存 Cookie
Typecho_Cookie::set('typechoAgreeRecording', json_encode($agreeRecording));
}
// 更新点赞字段,让点赞字段 +1
$db->query($db->update('table.contents')->rows(array('agree' => (int)$agree['agree'] + 1))->where('cid = ?', $cid));
// 查询出点赞数量
$agree = $db->fetchRow($db->select('table.contents.agree')->from('table.contents')->where('cid = ?', $cid));
// 返回点赞数量
return $agree['agree'];
}
上面的函数也很简单,下面是说明:
- 获取点赞记录的 Cookie。
- 如果 Cookie 不存在就创建一个。
- 判断文章是否点赞过。
- 如果文章点赞过就不再往下执行。
- 把文章的
cid
添加到点赞记录的 Cookie 中。 - 更新点赞字段。
- 查询出点赞数量。
- 返回点赞数量。
点赞记录的 Cookie 是一个 JSON 字符串,需要读取或更改的时候就需要转换为 PHP 对象,更改完成后需要转换为 JSON 字符串写入 Cookie。
点赞记录的 Cookie 中保存着文章的 cid
,每次点赞 文章的 cid
就会被加到 Cookie 中。如果要判断文章是否点赞过就可以判断文章的 cid
是否存在。
文章页
Typecho 用来输出文章的文件是 post.php
,处理点赞和展示点赞数量就需要在这个文件中编写。
下面是处理点赞的部分:
// 判断是否是点赞的 POST 请求
if (isset($_POST['agree'])) {
// 判断 POST 请求中的 cid 是否是本篇文章的 cid
if ($_POST['agree'] == $this->cid) {
// 调用点赞函数,传入文章的 cid,然后通过 exit 输出点赞数量
exit(agree($this->cid));
}
// 如果点赞的文章 cid 不是本篇文章的 cid 就输出 error 不再往下执行
exit('error');
}
上面的点赞处理需要放到 post.php
的顶部,也就是放到 HTML 代码的前面。这里如果判断是点赞请求就只会处理点赞,不会往下执行。
我的点赞数量是显示在点赞按钮中的,下面是显示输出点赞数量和点赞按钮。
获取点赞数量:
<?php $agree = $this->hidden?array('agree' => 0, 'recording' => true):agreeNum($this->cid); ?>
上面首先判断文章是否加密,如果加密就把点赞数设置为 0,然后禁止点赞,否则就调用函数获取点赞数量。
点赞按钮:
<button <?php echo $agree['recording']?'disabled':''; ?> type="button" id="agree" data-cid="<?php echo $this->cid; ?>" data-url="<?php $this->permalink(); ?>">
<span>赞</span>
<span class="agree-num"><?php echo $agree['agree']; ?></span>
</button>
注意文章按钮有两个自定义属性,data-cid
存储文章的 cid
,JS 发送 AJAX 请求的时候会用到,data-url
文章的 URL,发送 AJAX 请求的 URL。
上面如果文章被点赞过 PHP 就会输出 disabled
来禁用按钮。
JavaScript 点赞
我这里用到了 jQuery,下面是点赞代码:
// 点赞按钮点击
$('#agree-btn').on('click', function () {
$('#agree-btn').get(0).disabled = true; // 禁用点赞按钮
// 发送 AJAX 请求
$.ajax({
// 请求方式 post
type: 'post',
// url 获取点赞按钮的自定义 url 属性
url: $('#agree-btn').attr('data-url'),
// 发送的数据 cid,直接获取点赞按钮的 cid 属性
data: 'agree=' + $('#agree-btn').attr('data-cid'),
async: true,
timeout: 30000,
cache: false,
// 请求成功的函数
success: function (data) {
var re = /\d/; // 匹配数字的正则表达式
// 匹配数字
if (re.test(data)) {
// 把点赞按钮中的点赞数量设置为传回的点赞数量
$('#agree-btn .agree-num').html(data);
}
},
error: function () {
// 如果请求出错就恢复点赞按钮
$('#agree-btn').get(0).disabled = false;
},
});
});
点赞后被点赞的文章的点赞按钮会被禁用,只有点赞记录的 Cookie 到期或清除后才能再次点赞。
以上就是 Typecho 点赞功能的代码和详细说明,上面的函数和代码放到其它主题中也能使用,JS 部分需要依赖 jQuery。
相关文章:
版权声明:本文为原创文章,版权归 Mr. Ma's Blog 所有,转载请联系博主获得授权。
本文地址:https://www.misterma.com/archives/880/
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。
你好,用了这个功能以后会导致顶部的添加点赞功能处以上的按钮失效,请问怎么解决
// 把点赞按钮中的点赞数量设置为传回的点赞数量
这一段回传代码错误,导致了按钮失效,请问可以赞吗改
你点赞完成后,PHP 是否返回点赞数量的数字?你可以使用 console.log 输出查看一下
想问一下就是文章页的部分获取点赞数量是直接放在处理点赞的后面吗?还有就是后面的js点赞的代码是要放在什么位置或者哪个地方呢?刚玩这个不是很懂😂
处理点赞需要放到 post.php 的最前面,获取点赞数量可以放到点赞按钮的前面,JS 代码直接放到 JS 文件中,只要 JS 文件在文章页能被加载就可以。
[...]在/usr/themes/handsome/functions.php中添加(参考Typecho 主题开发 - 点赞功能)[...]
[...]原文转载:https://www.misterma.com/archives/880/[...]
可以可以,正好在本地搭建研究研究?
好文章,值得研究一下
路过
小白只能看看,来踩踩
你好我最近用了typecho,觉得你的模板不错,选择了你的模板。可是我放在了自己的服务器上。打开网页后发现,所有的css,js,jquery都找不到,能不能帮我看看什么原因吗?平常有点忙,谢谢1
我知道了原因
什么原因,发出来看看。
评论点赞要怎么做呢?
评论点赞也是差不多的方法,只不过需要在 typecho_comments 表中操作,ID 也需要用评论的 ID。评论点赞比起文章点赞可能会稍微麻烦一些,但方法都是差不多的。