Mr丶冷文

文章 分类 评论
76 8 2027

站点介绍

冷文学习者(KEVINLU98.COM),记录一个北漂小码农的日常业余生活
顺带帮大家免费代下载IT教程吧的资源 传送门
友链申请地址(直接评论即可): 传送门

Typecho非插件实现Cookie点赞功能

MR丶冷文 2021-03-28 1079 2条评论 typecho相关 typecho点赞非插件

首页 / 正文
Freewind主题v1.4版本已经发布,详情与下载请关注 Freewind1.4更新重要: 有关于Freewind主题的问题请在留言板留言,留言板我每天都会看的

发布于2022-01-10

说明

最近开发完了Freewind主题,把在开发过程中用到的一些Typecho本身不支持但又比较常用的功能总结一下分享给大家

效果

废话先不说,直接看效果

https://imagebed-1252410096.cos.ap-nanjing.myqcloud.com/20210328/23a64aeb292147c2b48d89564446a5e4.gif

想法

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>
  • 显示效果图如下

https://imagebed-1252410096.cos.ap-nanjing.myqcloud.com/20210328/fdff2bb38cde4811a7294a6b8c39025e.png

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();
}
  • 引入jquerylayer库,这个根据自身需要引入

这里用了jquerylayer,点赞后的事件请自行根据需求来编写

<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主题已经支持该工能啦

评论(2)

  1. 江河三千里 游客 2022-01-05 00:30 回复

    请问这个php文件中的function应该加在什么地方啊

    1. MR丶冷文 管理员 2022-01-05 10:08 回复

      @江河三千里

      function.php

热门文章

最新评论

  • 挽离

    学习一下

  • 挽离

    l来学习一下

  • 路过

    支持一下

  • 南柯一梦

    支持一下

  • 1

    学习一下

日历

2022年01月

      1
2345678
9101112131415
16171819202122
23242526272829
3031     

文章目录

站点公告
Freewind主题v1.4版本已经发布,详情与下载请关注 Freewind1.4更新重要: 有关于Freewind主题的问题请在留言板留言,留言板我每天都会看的
点击小铃铛关闭
配色方案