ajax无刷新提交评论对于提高用户评论有很好的用户体验,本教程将展示如何不修改主题代码的情况下,用hook来实现ajax无刷新提交评论的功能。

本教程的优点如下:

  • 最需要的功能之一 - 支持嵌套评论comment-reply.js。
  • 应正确显示所有评论错误。为简单起见,我将在本文中使用JavaScript alert()函数。
  • 从评论文本中删除不允许的HTML标记。
  • 评论审核。
  • 在Cookie中保存用户名和电子邮件字段的值。
  • 没有WordPress插件。没有插件:)

步骤一

由于每个主题的评论表单的结构不一样。我们采用默认的TwentySeventeen主题来示范,不过国外大多数主题的评论结构都一样的,及如下的结构:

<!-- it can be <ul> or <ol> element -->
<ol class="comment-list">
  <!-- more classes can be inside, we need only "comment" and "depth-#" -->
  <li id="comment-1" class="comment depth-1">
    <!-- article tag can also have ID and Classes but it doesn't matter for us -->
    <article>
      <!-- comment content and comment meta is here -->
      <!-- just make sure that <div class="reply"> is the last element inside article -->
      <div class="reply">
        <a class="comment-reply-link">Reply</a>
      </div>
    </article>
    <!-- nested comment replies are here  -->
    <ol class="children">
 
      <!-- comment <li> elements are the same like in depth-1 level -->
 
    </ol>
  </li>
</ol>
<div id="respond">
  <!-- form is here -->
  <!-- make sure that all the name attributes and ID of the <form> are correct -->
</div>

如果不一致,在步骤三把相应的id和class改成你的现有主题的就行了。

步骤二

在functions.php里引用下面的代码:

add_action( 'wp_enqueue_scripts', 'misha_ajax_comments_scripts' );
 
function misha_ajax_comments_scripts() {
 
  // I think jQuery is already included in your theme, check it yourself
  wp_enqueue_script('jquery');
 
  // just register for now, we will enqueue it below
  wp_register_script( 'ajax_comment', get_stylesheet_directory_uri() . '/ajax-comment.js', array('jquery') );
 
  // let's pass ajaxurl here, you can do it directly in JavaScript but sometimes it can cause problems, so better is PHP
  wp_localize_script( 'ajax_comment', 'misha_ajax_comment_params', array(
    'ajaxurl' => site_url() . '/wp-admin/admin-ajax.php'
  ) );
 
 	wp_enqueue_script( 'ajax_comment' );
}

步骤三

写入必要的js文件,我们的例子是在主题目录下新建一个ajax-comment.js文件。引入下面的代码:

/*
 * Let's begin with validation functions
 */
 jQuery.extend(jQuery.fn, {
  /*
   * check if field value lenth more than 3 symbols ( for name and comment ) 
   */
  validate: function () {
    if (jQuery(this).val().length < 3) {jQuery(this).addClass('error');return false} else {jQuery(this).removeClass('error');return true}
  },
  /*
   * check if email is correct
   * add to your CSS the styles of .error field, for example border-color:red;
   */
  validateEmail: function () {
    var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/,
        emailToValidate = jQuery(this).val();
    if (!emailReg.test( emailToValidate ) || emailToValidate == "") {
      jQuery(this).addClass('error');return false
    } else {
      jQuery(this).removeClass('error');return true
    }
  },
});
 
jQuery(function($){
 
  /*
   * On comment form submit
   */
  $( '#commentform' ).submit(function(){
 
    // define some vars
    var button = $('#submit'), // submit button
        respond = $('#respond'), // comment form container
        commentlist = $('.comment-list'), // comment list container
        cancelreplylink = $('#cancel-comment-reply-link');
 
    // if user is logged in, do not validate author and email fields
    if( $( '#author' ).length )
      $( '#author' ).validate();
 
    if( $( '#email' ).length )
      $( '#email' ).validateEmail();
 
    // validate comment in any case
    $( '#comment' ).validate();
 
    // if comment form isn't in process, submit it
    if ( !button.hasClass( 'loadingform' ) && !$( '#author' ).hasClass( 'error' ) && !$( '#email' ).hasClass( 'error' ) && !$( '#comment' ).hasClass( 'error' ) ){
 
      // ajax request
      $.ajax({
        type : 'POST',
        url : misha_ajax_comment_params.ajaxurl, // admin-ajax.php URL
        data: $(this).serialize() + '&action=ajaxcomments', // send form data + action parameter
        beforeSend: function(xhr){
          // what to do just after the form has been submitted
          button.addClass('loadingform').val('Loading...');
        },
        error: function (request, status, error) {
          if( status == 500 ){
            alert( 'Error while adding comment' );
          } else if( status == 'timeout' ){
            alert('Error: Server doesn\'t respond.');
          } else {
            // process WordPress errors
            var wpErrorHtml = request.responseText.split("<p>"),
              wpErrorStr = wpErrorHtml[1].split("</p>");
 
            alert( wpErrorStr[0] );
          }
        },
        success: function ( addedCommentHTML ) {
 
          // if this post already has comments
          if( commentlist.length > 0 ){
 
            // if in reply to another comment
            if( respond.parent().hasClass( 'comment' ) ){
 
              // if the other replies exist
              if( respond.parent().children( '.children' ).length ){	
                respond.parent().children( '.children' ).append( addedCommentHTML );
              } else {
                // if no replies, add <ol class="children">
                addedCommentHTML = '<ol class="children">' + addedCommentHTML + '</ol>';
                respond.parent().append( addedCommentHTML );
              }
              // close respond form
              cancelreplylink.trigger("click");
            } else {
              // simple comment
              commentlist.append( addedCommentHTML );
            }
          }else{
            // if no comments yet
            addedCommentHTML = '<ol class="comment-list">' + addedCommentHTML + '</ol>';
            respond.before( $(addedCommentHTML) );
          }
          // clear textarea field
          $('#comment').val('');
        },
        complete: function(){
          // what to do after a comment has been added
          button.removeClass( 'loadingform' ).val( 'Post Comment' );
        }
      });
    }
    return false;
  });
});

步骤四

创建评论输出,在步骤二的functions.php的代码后面加入下面的代码:

add_action( 'wp_ajax_ajaxcomments', 'misha_submit_ajax_comment' ); // wp_ajax_{action} for registered user
add_action( 'wp_ajax_nopriv_ajaxcomments', 'misha_submit_ajax_comment' ); // wp_ajax_nopriv_{action} for not registered users
 
function misha_submit_ajax_comment(){
  /*
   * Wow, this cool function appeared in WordPress 4.4.0, before that my code was muuuuch mooore longer
   *
   * @since 4.4.0
   */
  $comment = wp_handle_comment_submission( wp_unslash( $_POST ) );
  if ( is_wp_error( $comment ) ) {
    $error_data = intval( $comment->get_error_data() );
    if ( ! empty( $error_data ) ) {
      wp_die( '<p>' . $comment->get_error_message() . '</p>', __( 'Comment Submission Failure' ), array( 'response' => $error_data, 'back_link' => true ) );
    } else {
      wp_die( 'Unknown error' );
    }
  }
 
  /*
   * Set Cookies
   */
  $user = wp_get_current_user();
  do_action('set_comment_cookies', $comment, $user);
 
  /*
   * If you do not like this loop, pass the comment depth from JavaScript code
   */
  $comment_depth = 1;
  $comment_parent = $comment->comment_parent;
  while( $comment_parent ){
    $comment_depth++;
    $parent_comment = get_comment( $comment_parent );
    $comment_parent = $parent_comment->comment_parent;
  }
 
 	/*
 	 * Set the globals, so our comment functions below will work correctly
 	 */
  $GLOBALS['comment'] = $comment;
  $GLOBALS['comment_depth'] = $comment_depth;
 
  /*
   * Here is the comment template, you can configure it for your website
   * or you can try to find a ready function in your theme files
   */
  $comment_html = '<li ' . comment_class('', null, null, false ) . ' id="comment-' . get_comment_ID() . '">
    <article class="comment-body" id="div-comment-' . get_comment_ID() . '">
      <footer class="comment-meta">
        <div class="comment-author vcard">
          ' . get_avatar( $comment, 100 ) . '
          <b class="fn">' . get_comment_author_link() . '</b> <span class="says">says:</span>
        </div>
        <div class="comment-metadata">
          <a href="' . esc_url( get_comment_link( $comment->comment_ID ) ) . '">' . sprintf('%1$s at %2$s', get_comment_date(),  get_comment_time() ) . '</a>';
 
          if( $edit_link = get_edit_comment_link() )
            $comment_html .= '<span class="edit-link"><a class="comment-edit-link" href="' . $edit_link . '">Edit</a></span>';
 
        $comment_html .= '</div>';
        if ( $comment->comment_approved == '0' )
          $comment_html .= '<p class="comment-awaiting-moderation">Your comment is awaiting moderation.</p>';
 
      $comment_html .= '</footer>
      <div class="comment-content">' . apply_filters( 'comment_text', get_comment_text( $comment ), $comment ) . '</div>
    </article>
  </li>';
  echo $comment_html;
 
  die();
 
}

本教程来自:https://rudrastyh.com/wordpress/ajax-comments.html

发表评论