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
- 提示:这篇文章发布于 2019/05/15,作者 99839,总计 6654 字.
- 原文: WordPress无插件实现ajax无刷新提交评论 | 爱壹主题