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。
发表评论 | 暂无评论