Hi!请登陆

Typecho 自定义路由接口方法 – 给主题集成 Like 插件点赞喜欢功能

2020-11-2 48 11/2

先简单说明一下路由接口,路由接口的功能就是 Typecho 根据客户端的访问请求,找到系统中对应的控制器,然后执行相关功能。可能比较难以理解,下面举个例子说明应该就比较看得懂了。

需求
当下使用较多的点赞功能应该就是 skylzl 大佬开发的 Like 插件了,实际使用中发现在 iOS 浏览器 Safari 环境下,存在可以无限次点赞功能。经排查发现,插件使用 Cookie 来识别是否执行了点赞动作,但是采用的 Cookie 插件对 Safari 支持不好,无法正确写入、读取 Cookie。

基于此问题背景,加上能少装插件就少装插件的目标,故考虑将 Like 核心功能集成到 ArmxMod for Typecho 主题中。

分析
点赞功能按实现流程,可以分为:

前端按钮点赞(JavaScript)--> 后端主题接收请求(PHP)--> 后端主题处理请求并反馈处理结果给前端(PHP) --> 前端根据反馈处理点赞结果(JavaScript)

实现
前端点赞
这部分比较简单,先指定点赞入口:

<a href="javascript:;" class="post-like" data-pid="'.$cid.'" id="pluszan">赞</a>

然后 JavaScript 绑定点击动作,并向后端发出请求:

var likeup = '/action/like?up';
$('.post-like').on('click', function(e){
    var id = $(this).attr('data-pid');
    $.post(likeup,{
        cid:id
    }
});

这里可以看到,我们使用了 Ajax 异步请求,所以应保证网站已经引入 jquery 库。

接收请求
这一部分即是路由接口需要做的事情,当前端点赞时,后端如何知道前端进行了点赞,参照代码:

function themeInit($self) {
......
        if ($self->is('archive',404)){
                $path_info = trim($self->request->getPathinfo(),'/');
                if(strpos($path_info,'action/like') !== false){
                        header( "HTTP/1.1 200 OK" );
                        likeup($self);
                        $self->response->goBack();
                        exit;
                }
        }
......
}

路由接口需要在启用主题时就进行定义,所以应该在接口定义放在 Typecho function.php 的 themeInit 功能中。

这里我定义的路由是 /action/like,如果请求匹配到,则执行点赞后端处理函数 likeup()。

后端处理
后端主要处理的动作是,当接收到点赞时,对该文章的点赞数进行 +1,并返回 success 标志告诉前端已经处理完成,参照代码:

function likeup($self) {
        $cid = $self->request->filter('int')->cid;
        $self->db = Typecho_Db::get();
        $row = $self->db->fetchRow($self->db->select('likes')->from('table.contents')->where('cid = ?', $cid));
        $self->db->query($self->db->update('table.contents')->rows(array('likes' => (int)$row['likes']+1))->where('cid = ?', $cid));
        $self->response->throwJson("success");
}

前端处理
前端处理这一部分可有可无,如果需要针对后端处理结果,在前端做出响应,就要进一步处理,如果不处理也无大碍就是。需要注意的是,后端处理可能会花费较长时间才会有响应,造成前端困扰,因此鉴于是否响应无关紧要,我们可以直接在前端点赞时就给予反馈,比如提示“点赞成功”等等。

最后,本文中的范例仅作为参考,实际使用应根据环境做相应修改,比如增加请求校验等等。

相关推荐