首页
微语
统计
友链
留言
memos
圈子
图床
推荐
相册
网站监控
VPS监控
Search
1
实现typecho微信时光机功能的图文教程
45,235 阅读
2
为Typecho添加webp解析
43,190 阅读
3
emlog数据成功迁移到typecho
26,741 阅读
4
Memos备忘录,记录瞬间想法
25,724 阅读
5
Jasmine - 简约、美观的博客主题
24,395 阅读
手机达人
免费资源
电脑网络
娱乐休闲
网站建设
威言威语
Typecho
Emlog
WordPress
服务器
主题
插件
排行榜    
登录
/
注册
Search
标签搜索
wordpress
发布
插件
免费
教程
typecho
EMlog
PHP
代码
CSS
华为
图片
代码修改
安装
评论
手机
诺基亚
微信
文章
智能
Chen'mo
累计撰写
1,266
篇文章
累计收到
374
条评论
首页
栏目
手机达人
免费资源
电脑网络
娱乐休闲
网站建设
威言威语
Typecho
Emlog
WordPress
服务器
主题
插件
页面
微语
统计
友链
留言
memos
推荐
相册
网站监控
VPS监控
搜索到
3
篇与
的结果
2021-05-22
typecho 实现评论Cookie点赞功能
搞了一个动态发布页面,之前已经有了回复功能,总觉得还差点什么,折腾了好长时间,终于把遗缺的点赞功能加上了。先看效果https://xwsir.cn/talk.html后端处理1、 在核心文件 core.php 的初始化函数 function themeInit($self) 下添加if ($self->request->isPost() && $self->request->is('action=support')) { $res = _addSupport($self->request->get('coid')); $json = [ 'success' => $res ? true : false, 'count' => $res ]; ob_clean(); echo json_encode($json); exit(); }2、 在公用函数 function.php 中末尾地方添加function _getSupport($coid) { $db = Typecho_Db::get(); $prefix = $db->getPrefix(); if (!array_key_exists('support', $db->fetchRow($db->select()->from('table.comments')))) { $db->query('ALTER TABLE `' . $prefix . 'comments` ADD `support` INT(10) DEFAULT 0;'); return [ 'icon' => 'icon-unlike', 'count' => 0, 'text' => '点赞' ]; } $row = $db->fetchRow($db->select('support')->from('table.comments')->where('coid = ?', $coid)); $support = Typecho_Cookie::get('extend_comments_support'); if (empty($support)) { $support = array(); } else { $support = explode(',', $support); } if (!in_array($coid, $support)) { return [ 'icon' => 'icon-unlike', 'count' => $row['support'], 'text' => '点赞' ]; } else { return [ 'icon' => 'icon-like', 'count' => $row['support'], 'text' => '已赞' ]; } } function _addSupport($coid) { $db = Typecho_Db::get(); $row = $db->fetchRow($db->select('support')->from('table.comments')->where('coid = ?', $coid)); $support = Typecho_Cookie::get('extend_comments_support'); if (empty($support)) { $support = array(); } else { $support = explode(',', $support); } if (!in_array($coid, $support)) { $db->query($db->update('table.comments')->rows(array('support' => (int)$row['support'] + 1))->where('coid = ?', $coid)); array_push($support, $coid); $support = implode(',', $support); Typecho_Cookie::set('extend_comments_support', $support); return $row['support'] + 1; } else { return false; } }前端处理----php1、 在需要显示的页面中添加<div class="item"> <?php $suport = _getSupport($comments->coid) ?> <i class="iconfont <?php echo $suport['icon'] ?>"> <a class="support" data-coid="<?php echo $comments->coid ?>" href="javascript:void (0)"> <?php echo '(' . $suport['count'] . ')' . $suport['text'] ?> </a> </i> </div>2、 在 js 处理文件中添加$('.support').on('click', function () { $.ajax({ url: `/?action=support`, type: 'POST', data: { coid: $(this).data('coid') }, dataType: 'json', success: res => { if (res.success) { Qmsg.success('谢谢点赞~'); $(this).parent().removeClass('icon-unlike').addClass('icon-like'); $(this).text('(' + res.count + ')' + '已赞'); } else { Qmsg.warning('您已赞过~'); } } }); });3、 在 css 样式文件中添加.item { .support { font-size: 14px; color: var(--minor); &:hover { color: var(--theme); } } .icon-like { &:before { color: var(--theme); } } }4、 引入图标库文件,这里用到是阿里巴巴图标库<link rel="stylesheet" href="//at.alicdn.com/t/font_2524811_dm4ygqk8eqo.css">
2021年05月22日
3,526 阅读
1 评论
14 点赞
2021-05-20
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。
2021年05月20日
3,698 阅读
0 评论
19 点赞
2021-02-22
Typecho 主题点赞功能实现
有人问到点赞功能,这里抽取代码分享一下,因为去掉了部分敏感信息,可能需要调试一下。我的设计思路是使用自定义字段来存储点赞次数。和市面上的方案不一样,不过大同小异。增加接口首先要修改functions.php的themeInit函数,加入点赞接口function themeInit($archive) { if ($archive->is('single')) { if ($archive->request->isPost()) { if ($archive->request->is('themeAction=promo')) { promo($archive); } } } } 接着要加入点赞核心函数,下面的函数可以扩展/** * Post Action AJAX接口 * * @param Widget_Archive $widget * @return void * @date 2020-05-04 */ function promo($widget) { $user = $widget->widget('Widget_User'); $db = Typecho_Db::get(); $fields = unserialize($widget->fields); $allowOperates = array('get', 'set', 'inc', 'dec'); // 这里可以扩展操作,建议屏蔽get/set $allowFields = array('likes'); // 这里可以扩展修改字段 // 获取操作 $operate = $widget->request->get('operate'); $field = $widget->request->get('field'); $value = $widget->request->filter('int')->get('value'); $value = $value === null ? 100 : $value; // 100 起步 $result = array('cid' => $widget->cid); if ($operate === "get") { $result['operate'] = 'get'; if (array_key_exists($field, $fields)) { $result[$field] = $fields[$field]; } else { $result[$field] = -1; } $widget->response->throwJson(array('status' => 1, 'msg' => _t('已获取参数'), 'result' => json_encode($result))); } elseif ($operate === "set") { $result['operate'] = 'set'; if ($value > 0) { $widget->setField($field, 'str', $value, $widget->cid); } else { $db->query($db->delete('table.fields') ->where('cid = ? AND name = ?', $widget->cid, $field)); } $widget->response->throwJson(array('status' => 1, 'msg' => _t('已完成操作'), 'result' => json_encode($result))); } elseif ($operate === "inc") { $result['operate'] = 'inc'; $value = intval($fields[$field]) + 1; $widget->setField($field, 'str', $value, $widget->cid); $result[$field] = $value; $widget->response->throwJson(array('status' => 1, 'msg' => _t('已完成操作'), 'result' => json_encode($result))); } elseif ($operate === "dec") { $result['operate'] = 'dec'; $value = intval($fields[$field]) - 1; $result[$field] = $value; if ($value > 0) { $widget->setField($field, 'str', $value, $widget->cid); } else { $db->query($db->delete('table.fields') ->where('cid = ? AND name = ?', $widget->cid, $field)); } $widget->response->throwJson(array('status' => 1, 'msg' => _t('已完成操作'), 'result' => json_encode($result))); } } Post 请求参数说明operate:操作 field: 操作字段 value:操作值,inc/dec 操作用不到 前端方面这里我给出我的参考 js 代码,实际建议自己写一下,使用 jq 也不复杂。function likesCallback(count) { $("#likesPostCount").value(count); } $("#likesPost").click(function () { posturl = $(location).attr("href").split("?")[0] + "?themeAction=promo"; $.ajax({ url: posturl, type: "POST", data: { operate: "inc", field: "likes" }, dataType: "json", success: function (result) { if (1 == result.status) { result = JSON.parse(result.result) likes = undefined === result.likes ? -1 : result.likes; likesCallback(result.likes); } else { // 提醒错误消息 alert( undefined === result.msg ? '点赞失败' : result.msg ); } }, error: function (xhr, ajaxOptions, thrownError) { alert('点赞失败' + ajaxOptions); }, }); }); 输出因为使用自定义字段存储,所以输出和普通自定义字段一样<?php echo $this->fields->likes; ?>
2021年02月22日
5,574 阅读
0 评论
7 点赞