WordPress: come implementare un sistema di votazione dei post

Creare un sistema di votazione dei post in WordPress significa semplicemente utilizzare i custom fields e AJAX.

Per prima cosa creiamo la action AJAX in WordPress:


    function my_ajax_vote() {
        $action_type = $_GET['type']; // Tipo di azione
        $post_id = $_GET['id']; // ID del post
        $allowed_types = array( 'bad', 'good' ); // Azioni consentite
        
        // Validazione
        if( in_array( $action_type, $allowed_types ) && is_numeric( $post_id ) ) {
            $id = (int) $post_id;
            $bad_vote_field = get_post_meta( $id, 'bad_vote', true ); // Custom field del voto negativo
            $good_vote_field = get_post_meta( $id, 'good_vote', true ); // Custom field del voto positivo
            switch( $action_type ) {
                case 'bad':
                    if( $bad_vote_field == '' ) {
                        update_post_meta( $id, 'bad_vote', '1' );
                    } else {
                         $bad_vote = (int) $bad_vote_field;
                         $bad_vote++;
                         update_post_meta( $id, 'bad_vote', $bad_vote );
                    }
                    break;
                case 'good':
                    if( $good_vote_field == '' ) {
                        update_post_meta( $id, 'good_vote', '1' );
                    } else {
                         $good_vote = (int) $good_vote_field;
                         $good_vote++;
                         update_post_meta( $id, 'good_vote', $good_vote );
                    }
                    break;
                 default:
                    break;
               }
               echo '1';
               exit();
        } else {
            exit();
        }
    }

    add_action( 'wp_ajax_my_vote', 'my_ajax_vote' );
    add_action( 'wp_ajax_nopriv_my_vote', 'my_ajax_vote' );

Come noterete si tratta solo di incrementare due contatori e salvarli nei rispettivi custom field. La nostra funzione accetta due parametri GET:

  1. type: ci comunica quale custom field utilizzare
  2. id: ID numerico del post corrente.

Ora possiamo creare la struttura associata nel nostro tema:


	<article class="post">
        <!-- contenuto del post -->
        <div class="rating">
	        <?php $good = ( get_post_meta( get_the_ID(), 'good_vote', true ) !== '' ) ? get_post_meta( get_the_ID(), 'good_vote', true ) : '0';
	              $bad = ( get_post_meta( get_the_ID(), 'bad_vote', true ) !== '' ) ? get_post_meta( get_the_ID(), 'bad_vote', true ) : '0';
	         ?>
             <p>Come valuti questo post?</p>
             <div class="rating-buttons">
                 <a class="good-btn" href="#" data-postid="<?php the_ID(); ?>" data-type="good">Buono 
	                 <span class="rate-count"><?php echo $good; ?></span></a>
                  <a class="bad-btn" href="#" data-postid="<?php the_ID(); ?>" data-type="bad">Mediocre 
	                  <span class="rate-count"><?php echo $bad; ?></span></a>
             </div>
        </div>
    </article>

Quindi possiamo creare un semplice plugin jQuery:


    (function( $ ) {
        $.fn.ratePost = function( options ) {
            options = $.extend({
                 action: "my_vote",
                 count: ".rate-count"
            }, options);
            
            return this.each(function() {
                var $element = $( this ),
                    url = "http://" + location.host + "/wp-admin/admin-ajax.php",
                    postID = $element.data( "postid" ),
                    type = $element.data( "type" ),
                    data = {
                       action: options.action,
                       id: postID,
                       type: type
                     },
                     $count = $( options.count, $element );
                     
                     $element.on( "click", function( e ) {
                         e.preventDefault();
                         $.when( $.get( url, data ) ).done(function( output ) {
						 	if( output == "1" ) {
                            	var count = parseInt( $count.text(), 10 );
                            	var n = count++;
                            	$count.text( n.toString() );  
						 	}
						 });
                      });
               });
        };
    })( jQuery );

Infine possiamo utilizzare il nostro plugin come segue:


$(function() {
	$( "a", ".rating-buttons" ).ratePost();	
	
});