wordpress进阶教程(三十一):ajax实现文章顶踩

本篇教程要实现的内容为文章定踩功能,或者说“喜欢”“不喜欢”。

应用实例:

wordpress顶踩功能

实现步骤:

本实例以上图所示喜欢和不喜欢为例。

一、新建数据表

新建数据表,将文章投票数据保存在新的数据表中,我们需要记录用户ID,文章ID,投票内容,用户ip,新数据表如下:投票功能数据表

实现新建数据表代码如下,将代码添加进主题的functions.php(或自定)文件中:

  1. /*********更新重写规则***************/  
  2. function ashu_load_theme() {   
  3.     global $pagenow;   
  4.     if ( is_admin() && 'themes.php' == $pagenow && isset( $_GET['activated'] ) )   
  5.         ashu_vote_install(); //激活主题的时候执行函数   
  6. }   
  7. add_action( 'load-themes.php', 'ashu_load_theme' );   
  8. function ashu_vote_install(){   
  9.     global $wpdb;   
  10.     //创建 _post_vote表   
  11.     $table_name = $wpdb->prefix . 'post_vote';   
  12.     if$wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name ) :   
  13.     $sql = " CREATE TABLE `".$wpdb->prefix."post_vote` (
  14.       `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY ,  
  15.       `user` INT NOT NULL ,  
  16.       `post` INT NOT NULL ,  
  17.       `rating` varchar(10),  
  18.       `ip` varchar(40)  
  19.      ) ENGINE = MYISAM DEFAULT CHARSET=utf8;";   
  20.         require_once(ABSPATH . 'wp-admin/includes/upgrade.php');   
  21.         dbDelta($sql);   
  22.     endif;   
  23. }  

二、准备投票和查询函数

准备数据库操作函数,包括添加数据函数和查询数据,将如下函数代码也添加到主题的functions.php文件(或自定):

1、添加数据函数

  1. /*  
  2. *添加投票函数  
  3. *$post_id 文章id  
  4. *$user_id 用户ID  
  5. *$ip 用户IP  
  6. *$rating 投票内容  
  7. */  
  8. function add_vote($post_id,$user_id='',$ip='',$rating='up'){   
  9.     global $wpdb;   
  10.     $user_id = (int)$user_id;   
  11.     $post_id = (int)$post_id;   
  12.     if(($user_id=='')&&($ip=='')){   
  13.         return "e"//返回error   
  14.     }   
  15.     //检查用户对某一文章是否已经投票票了   
  16.     if($user_id!=''){   
  17.         $check"select * from ".$wpdb->prefix."post_vote where post='$post_id' and user='$user_id'";   
  18.     }else{   
  19.         if($ip!=''){   
  20.             $check"select * from ".$wpdb->prefix."post_vote where post='$post_id' and ip='$ip'";   
  21.         }   
  22.     }   
  23.     $coo = $wpdb->get_results($check);   
  24.     //投票内容只能是up或者down   
  25.     if($rating=='up'){   
  26.         $rating='up';   
  27.     }else{   
  28.         $rating='down';   
  29.     }   
  30.     //如果不存在数据   
  31.     if(!count($coo) > 0){   
  32.         //插入数据 sql   
  33.         $s = "insert into ".$wpdb->prefix."post_vote (user,post,rating,ip) values('$user_id','$post_id','$rating','$ip')";   
  34.         $wpdb->query($s);   
  35.         return "y"//返回yes   
  36.     }else{   
  37.         return "h"//返回have   
  38.     }   
  39.     return "e";//返回error   
  40. }  

2、查询投票数据函数

比如查询某文章点击up的数据,则使用 get_post_vote(1,'up');

  1. /*   
  2. *获取文章投票数据   
  3. *$post_id 文章ID   
  4. *$vote 投票内容   
  5. */   
  6. function get_post_vote($post_id,$vote='up'){   
  7.     global $wpdb;   
  8.     $post_id = (int)$post_id;   
  9.     if($vote == 'up'){   
  10.         $vote='up';   
  11.     }else{   
  12.         $vote='down';   
  13.     }   
  14.     //查询数据sql   
  15.     $sql = "select count(*) from ".$wpdb->prefix."post_vote where post='$post_id' and rating='$vote'";   
  16.     $coo = $wpdb->get_var($sql);   
  17.     if($coo)   
  18.     return $coo; //返回数据   
  19.     else   
  20.     return 0;   
  21. }  

三、准备前台html和js

建立好了新的数据表,也准备好了实现投票功能的函数,接下来看前台的html和js。

1、网页前台显示数据,将下面的代码放在输出文章的循环内,即常说的loop中。

  1. <span class="vote_up" id="<?php echo 'vote_up'.$post->ID;?>">   
  2.     <a href="javascript:void(0);" rel="<?php echo 'up_',$post->ID;?>">   
  3.     <span id="<?php echo 'vup'.$post->ID;?>">   
  4.         <?php echo get_post_vote($post->ID,'up');?>   
  5.     </span>   
  6.     </a>   
  7. 人认为值得买!</span>   
  8.   
  9. <span class="vote_down" id="<?php echo 'vote_down'.$post->ID;?>">   
  10.     <a href="javascript:void(0);" rel="<?php echo 'down_'.$post->ID;?>">   
  11.     <span id="<?php echo 'vdown'.$post->ID;?>">   
  12.         <?php echo get_post_vote($post->ID,'down');?>   
  13.     </span>   
  14.     </a>人认为不值得买!   
  15. </span>  

上面代码将会输出一个如下的html结构

  1. <span class="vote_up" id="vote_up44">  
  2.     <a href="javascript:void(0);" title="值得" rel="up_44">  
  3.     <span id="vup44">  
  4.         0   
  5.     </span>  
  6.     </a>  
  7. 人认为值得买!</span>  
  8. <span class="vote_down" id="vote_down44">  
  9.     <a href="javascript:void(0);" title="不值" rel="down_44">  
  10.     <span id="vdown44">  
  11.         1   
  12.     </span>  
  13.     </a>人认为不值得买!   
  14. </span>  

四、js代码
本篇教程中和上一篇一样,我们同样使用jquery发起ajax请求,所以首先在网页头部加载jquery代码,我在主题底部文件footer.php中加载jqeury。我将jquery-1.7.2.min.js放在了主题文件夹的js文件夹里面,所以用get_template_directory_uri()函数来输出主题的url

  1. <script src="<?php echo get_template_directory_uri();?>/js/jquery-1.7.2.min.js"></script>   

然后我将发起ajax请求代码也放在了主题里面js文件夹中的ashu.js文件,所以再加上一个

其中输出了ajax请求的地址:www.ashuwp.com/wp-admin/admin-ajax.php
  1. <script type="text/javascript">var ajax_url = '<?php echo admin_url(); ?>admin-ajax.php';</script>  
  2. <script src="<?php echo get_template_directory_uri();?>/js/ashu.js"></script>    

ashu.js文件中的代码

  1. /**     
  2.  * by ashu.     
  3.  * URI: http://www.ashuwp.com     
  4.  */   
  5.   
  6. /**   
  7.  * 获取Cookie   
  8.  *name  cookie名称   
  9.  */   
  10. function getCookie(name) {   
  11.     var start = document.cookie.indexOf( name + "=" );   
  12.     var len = start + name.length + 1;   
  13.   
  14.     if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) )   
  15.         return null;   
  16.   
  17.     if ( start == -1 )   
  18.         return null;   
  19.   
  20.     var end = document.cookie.indexOf( ';', len );   
  21.   
  22.     if ( end == -1 )   
  23.         end = document.cookie.length;   
  24.     return unescape( document.cookie.substring( len, end ) );   
  25. }   
  26. function ashu_isCookieEnable() {   
  27.     var today = new Date();   
  28.     today.setTime( today.getTime() );   
  29.     var expires_date = new Date( today.getTime() + (1000 * 60) );   
  30.   
  31.     document.cookie = 'ashu_cookie_test=test;expires=' + expires_date.toGMTString() + ';path=/';   
  32.     var cookieEnable = (getCookie('ashu_cookie_test') == 'test') ?  true : false;   
  33.     //document.cookie = 'ludou_cookie_test=;expires=Fri, 3 Aug 2001 20:47:11 UTC;path=/';   
  34.     return cookieEnable;   
  35. }   
  36.     
  37. jQuery(document).ready(function($) {   
  38.     var ashu_token = 1;   
  39.     $('.vote_up a').click(function(){   
  40.         //检查浏览器是否启用cookie功能   
  41.         if( !ashu_isCookieEnable() ) {   
  42.             alert("很抱歉,您不能给本文投票!");   
  43.             return;   
  44.         }   
  45.         if( ashu_token != 1 ) {   
  46.             alert("您的鼠标点得也太快了吧?!");   
  47.             return false;   
  48.         }   
  49.         ashu_token = 0;   
  50.         //获取投票a标签中的rel值   
  51.         var full_info = $(this).attr( 'rel' );   
  52.         var arr_param = full_info.split( '_' ); //以字符"_"分割   
  53.         //发起ajax   
  54.         $.ajax({   
  55.             url:ajax_url, //ajax地址   
  56.             type:'POST',   
  57.             //请求的参数包括action   rating  postid三项   
  58.             data:'action=vote_post&rating=' + arr_param[ 0 ] + '&postid=' + arr_param[ 1 ],   
  59.             //返回数据   
  60.             success:function(results){   
  61.                 if(results=='n'){   
  62.                     alert('评价失败');   
  63.                     ashu_token = 1;   
  64.   
  65.                 }   
  66.                 if (results=='y'){   
  67.                     //如果成功,给前台数据加1   
  68.                     var upd_vd = 'vup' + arr_param[ 1 ];   
  69.                     $('#'+upd_vd).text(parseInt($("#"+upd_vd).text())+1);   
  70.                     ashu_token = 1;   
  71.                        
  72.                 }   
  73.                 if (results=='h'){   
  74.                     ashu_token = 1;   
  75.                     alert('已经发表过评价了');   
  76.                 }   
  77.                 if (results=='e'){   
  78.                     ashu_token = 1;   
  79.                     alert('评价失败');   
  80.                 }   
  81.             }   
  82.         });   
  83.     });   
  84.        
  85.     $('.vote_down a').click(function(){   
  86.         if( !ashu_isCookieEnable() ) {   
  87.             alert("很抱歉,您不能给本文投票!");   
  88.             return;   
  89.         }   
  90.         if(ashu_token != 1) {   
  91.             alert("您的鼠标点得也太快了吧?!");   
  92.             return false;   
  93.         }   
  94.         ashu_token = 0;   
  95.   
  96.         var full_info = $(this).attr( 'rel' );   
  97.         var arr_param = full_info.split( '_' );   
  98.         $.ajax({   
  99.             url:ajax_url,   
  100.             type:'POST',   
  101.             data:'action=vote_post&rating=' + arr_param[ 0 ] + '&postid=' + arr_param[ 1 ],   
  102.             success:function(results){   
  103.                 if(results=='n'){   
  104.                     alert('评价失败');   
  105.                     ashu_token = 1;   
  106.                 }   
  107.                 if (results=='y'){   
  108.                     var upd_vd = 'vdown' + arr_param[ 1 ];   
  109.                     $("#"+upd_vd).text(parseInt($("#"+upd_vd).text())+1);   
  110.                     ashu_token = 1;   
  111.                 }   
  112.                 if (results=='h'){   
  113.                     ashu_token = 1;   
  114.                     alert('已经发表过评价了');   
  115.                 }   
  116.                 if (results=='e'){   
  117.                     ashu_token = 1;   
  118.                     alert('发生未知错误');   
  119.                 }   
  120.             }   
  121.         });   
  122.     });   
  123. });  

五、后台php处理代码。

在前面的教程中,我们的ajax请求地址直接是网站页码地址,但是本篇教程中,我们的ajax请求地址是类似:www.ashuwp.com/wp-admin/admin-ajax.php

使用这个地址来处理ajax请求,请一定记得请求中需要有action参数,然后我们只需要在functions.php文件(或自定)中添加下马代码,即可处理我们的请求,注意执行完请求输出内容之后,添加die函数结束:

  1. /*   
  2. *wp的ajax都可以通过请求中的action参数来执行对应的钩子   
  3. *示例中我们的action参数值是vote_post   
  4. *所以我们可以直接用下面两个钩子来执行动作   
  5. */   
  6. add_action("wp_ajax_vote_post", "add_votes_options");   
  7. add_action("wp_ajax_nopriv_vote_post", "add_votes_options");   
  8. function add_votes_options() {   
  9.   
  10. if( isset($_POST['action']) && ($_POST['action'] == 'vote_post') ){   
  11.     $postid = (int)$_POST['postid'];   
  12.     if( !$postid ){   
  13.         echo 'e'; //输出error   
  14.         die(0);   
  15.     }   
  16.     //cookie中是否已经存在投票数据   
  17.     $voted = $_COOKIE["smzdm_voted_".$postid];   
  18.     if( $voted ){   
  19.         echo 'h'; //输出have   
  20.         die(0);   
  21.     }   
  22.     $ip = $_SERVER['REMOTE_ADDR'];//ip   
  23.     $rating = $_POST['rating']; //投票内容   
  24.     //判断用户是否登录   
  25.     if(  is_user_logged_in() ){   
  26.         global $wpdb, $current_user;   
  27.         get_currentuserinfo();   
  28.         $uid = $current_user->ID;   
  29.     }else{   
  30.         $uid='';   
  31.     }   
  32.     if($rating=='up'){   
  33.         $rating='up';   
  34.     }else{   
  35.         $rating='down';   
  36.     }   
  37.     //添加数据   
  38.     $voted = add_vote($postid,$uid,$ip,$rating);   
  39.     if($voted=='y'){   
  40.         //设置cookie   
  41.         setcookie("ashu_voted_" . $postid,$rating, time() + 3000000, '/');   
  42.         echo 'y';//输出yes   
  43.         die(0);   
  44.     }   
  45.     if($voted=='h'){   
  46.         //设置cookie   
  47.         setcookie("ashu_voted_" . $postid,$rating, time() + 3000000, '/');   
  48.         echo 'h';   
  49.         die(0);   
  50.     }   
  51.     if($voted=='e'){   
  52.         echo 'n';//输出no   
  53.         die(0);   
  54.     }   
  55. }else{   
  56.     echo 'e';//输出eroor   
  57. }   
  58. die(0);   
  59. }  

六、结束
本票教程并非实现定踩或喜欢功能的最佳选择,只是提供一个ajax的简单示例...

已有15条评论

  1. nikanaa
    nikanaa : 回复

    文章最后说这不是最佳方法 请问最佳方法是啥?

  2. 傻蛋
    傻蛋 : 回复

    代码太冗杂了,不实用

  3. 飞天猪
    飞天猪 : 回复

    不错,一个字喜欢

  4. 秋叶
    秋叶 : 回复

    檫,我整个主题的代码都没这么多~

  5. 地坛分享
    地坛分享 : 回复

    生成的头像好抽象。。

  6. laoan
    laoan : 回复

    期待实例讲解,最好是用gggg主题。谢谢树

  7. laoan
    laoan : 回复

    谢谢阿树,教程学习了一遍,虽然不能一下完全理解和掌握,但也学到了很多,谢谢。

    期待。。。

  8. sopole
    sopole : 回复

    创建数据库的时候是不是用after_setup_theme这个钩子方便些呢?http://codex.wordpress.org/Plugin_API/Action_Reference/after_setup_theme启动主题的时候进行一些初始化

    • 阿树工作室
      阿树工作室 回复sopole: 回复

      after_setup_theme钩子是在每次运行程序的时候,加载主题之后。。。

      但是新建数据表不需要每次运行都执行啊。。。执行一次就玩完了。。也就是安装启用主题的时候比较好。。。

      • sopole
        sopole 回复阿树工作室: 回复

        哦,原来如此,好像确实是那么回事,这样子说after_setup_theme这个钩子有啥用处?

        • 小猪
          小猪 回复sopole: 回复

          这个是测试,嘻嘻

        • 阿树工作室
          阿树工作室 回复sopole: 回复

          It is generally used to perform basic setup, registration, and init actions for a theme.

          一般用来执行一些基本设置,注册菜单、侧边栏、添加功能支持(比如特色图像)等….

          • sopole
            sopole 回复阿树工作室: 回复

            直接写在functions.php里不行么,为啥还要用这钩子

  9. sopole
    sopole : 回复

    直接使用get_post_meta不更好?也不用去新建一个表了

    • 阿树工作室
      阿树工作室 回复sopole: 回复

      使用post_meta的话,会造成meta表数据暴涨啊。。。

      新建数据表的话,便于清除数据吧

发表评论