首页 收藏 文章 闲言 友链

WordPress 主题开发:无刷新 ajax 提交评论

2019-05-24 13:06:35 浏览:122 编辑:郑妙忠

前言:ajax 提交评论听起来很复杂,其实只要获取几个参数,提交给后台,基本的无刷新提交就完成了。

前台js代码介绍

  var path = '/wp-admin/admin-ajax.php', // 提交的路径
      http = new XMLHttpRequest(), // js 原生 ajax
      data = []; // 要发送的数据变量

  data.push("comment=" + encodeURI("hello word!"));
  data.push("comment_post_ID=" + 3);
  data.push("comment_parent=" + 2);
  data.push("comment_mail_notify=" + true);
  data.push("_wp_unfiltered_html_comment=" + "e0250665c0");
  data.push("action=" + "ajax_comment");
  /*
    comment:评论内容,要用 encodeURI() 函数处理一下
    comment_parent:父评论的 ID,为 0 时代表没有父评论
    comment_mail_notify:是否邮件提醒
    action:设置提交到哪个地方,"ajax_comment" 必须和 function.php 里面设置的一致:
      add_action('wp_ajax_nopriv_ajax_comment', 'ajax_comment');
      add_action('wp_ajax_ajax_comment', 'ajax_comment');
      详细设置请往下查看“后台php代码介绍”。

    未登录的用户,需要提交多三个参数:
    data.push("_wp_unfiltered_html_comment=" + "e0250665c0"); // 验证字符串,已登录的用户才需要,自动生成
    data.push("author=" + "孤独求败"); // author 昵称,用户已登录时会自动获取提交
    data.push("email=" + "guduqiubai@qq.com"); // email 箱地址,用户已登录时会自动获取提交
    data.push("url=" + "https://www.guduqiubai.com/"); // url 网址,用户已登录时会自动获取提交

    要了解自动生成的字段请往下看“评论模板代码介绍”。
  */

  data = data.join("&"); // 需要转换成数据成类似'a=1&b=2&c=3'的格式

  http.open("POST", path, true); // POST 提交
  http.setRequestHeader("content-type", "application/x-www-form-urlencoded;charset=UTF-8");// 需要设置 content-type 为 application/x-www-form-urlencoded
  http.onreadystatechange=function(){
    if(this.readyState == 4){
      if(this.status == 200){
        // 这里可以做提交成功的处理,在文档中显示刚才提交的一条评论,这条评论的 html 结构,可以在后端拼接完返回 html 字符串,也可以在前端通过后台传回来的数据拼接 html 结构。
        console.log(this.responseText);
      }else if(this.status == 500){
        // 这里要做 500 判断,比如重复提交时会返回500错误
        console.log(this.responseText);
      }else{
        // 提交失败
        console.log("提交失败");
      }
    }
  }
  http.send(data);

评论模板代码介绍

上面已经知道 ajax 评论需要提交哪些字段,有一些字段是调用wp函数自动生成的。下面了解怎么生成,以及介绍几个评论相关接口的使用(获取评论数、判断当前文章是否开启评论、判断用户是否已登录等)。

涉及文件:comments.php

<?php
  // 自动生成 <input> 标签字段
  comment_id_fields();
  do_action('comment_form', $post->ID);
  /*
    一共生成三个 <input> 和 一个 <script>:
    <input type='hidden' name='comment_post_ID' value='553' id='comment_post_ID' />
    <input type='hidden' name='comment_parent' id='comment_parent' value='0' />
    <input type="hidden" id="_wp_unfiltered_html_comment_disabled" name="_wp_unfiltered_html_comment_disabled" value="e0250665c0" />
    <script>
      (function(){if(window===window.parent){document.getElementById('_wp_unfiltered_html_comment_disabled').name='_wp_unfiltered_html_comment';}})();
    </script>
  */
?>

<?php
  // 判断当前文章是否开启评论
  if ( !comments_open() ) return; // 如果当前文章评论未开启,则什么都不输出,直接返回

  // 输出当前文章评论数,不用使用 echo
  comments_number('0','1','%'); // '0' 是默认值, '1' 好像是占位用, '%' 只输出数字

  // 输出当前文章评论列表 Comment_Walker 为自定义 Walker 类,详情请查看《WordPress 主题开发:通过继承 Walker 类自定义菜单、评论列表 html 输出》
  wp_list_comments(array('walker' => new Comment_Walker()));

  /*** 页面主要结构 ***/
  if ( !is_user_logged_in() ) {// 判断用户是否登录
    if ( get_option('comment_registration'){// 判断是否需要登录才能评论
     /* 输出必须注册登陆才能评论表单 html */
    }
    /* 输出未登录就能评论的表单 html,昵称、邮箱、网址就写在这里 */
  }
  /* 输出文本域和提交按钮 */
?>

自定义 Walker 传送门:《WordPress 主题开发:通过继承 Walker 类自定义菜单、评论列表 html 输出》

后台php代码介绍

涉及文件:function.php

<?php
  // 这里是固定函数,别人好像都这么写
  function comment_err($a) {
    header('HTTP/1.0 500 Internal Server Error');
    header('Content-Type: text/plain;charset=UTF-8');
    echo $a;
    exit;
  }

  function ajax_comment(){
    /* 固定 */
    $comment = wp_handle_comment_submission( wp_unslash( $_POST ) );
    if ( is_wp_error( $comment ) ) {
      $data = $comment->get_error_data();
      if ( ! empty( $data )) {
        comment_err($comment->get_error_message());
      } else {
        exit;
      }
    }
    $user = wp_get_current_user();
    do_action('set_comment_cookies', $comment, $user);
    $GLOBALS['comment'] = $comment;
    /* 以上都是固定 */

    $id = get_comment_ID(); // 该评论的ID
    $name = get_comment_author(); // 评论者昵称
    $url = get_comment_author_url(); // 评论者的网址
    $date = get_comment_date(); // 评论的日期时间
    $avatar = get_avatar($comment, 64, '', $name, array('class' => 'rounded-circle comment-avatar')); // 获取评论头像,返回<img>
    $for = get_comment_author( $comment->comment_parent ); // $comment->comment_parent 获取父评论ID,get_comment_author() 通过评论ID获取评论者昵称,添加 @ 时使用

    // 评论内容处理,把换行符替换成<br>标签;把表情代码替换成<img>图片标签也在这里处理
    $content = str_ireplace(array("\r\n","\n"), "<br>", get_comment_text());

    if( $comment->comment_parent == 0 ){
      // 如果提交的评论没有父评论
      $output .= "$avatar<a href=\"$url\">$name</a>:$content";
    }else{
      $output .= "<a href=\"$url\">$name</a>:@$for $content";
    }
    echo $output;
    die();
  }
  add_action('wp_ajax_nopriv_ajax_comment', 'ajax_comment'); // 'ajax_comment' 是上面定义的函数名,而且要与前台 js 提交的 action 字段一致,下同
  add_action('wp_ajax_ajax_comment', 'ajax_comment'); // 同上
?>
END

留言 (共 0 条)