Cómo crear un sistema de puntuación simple con WordPress y jQuery
Spanish (Español) translation by CYC (you can also view the original English article)
Ya hay muchos plugins de sistemas de puntuación de publicaciones allí. Sorprendentemente, ninguna se ajusta a mis necesidades, ya sea que son demasiado complicadas o con demasiadas opciones integradas. Por lo tanto, en este tutorial, aprenderás cómo crear tu propia funcionalidad de calificación simple de entradas, directamente dentro de tus archivos del tema. ¡No hay necesidad de un plugin!
Paso 1: Introducción
Las calificaciones en las entradas son una buena manera de obtener retroalimentación acerca de lo que realmente se enfocan tus lectores. Mientras estaba buscando un plugin simple pero eficiente, me di cuenta de que todos vienen con demasiadas opciones y no son lo suficientemente personalizables. Ese fue mi primer problema. Mi segundo problema fue que usar demasiados plugins reduciría la velocidad de WordPress.
Así que decidí compartir contigo una manera de construir tu sistema personalizado de puntuaciones. Utilizaremos:
- Marcado simple en HTML y CSS3 para que sea fácil de personalizar.
- jQuery para hacer frente a las llamadas AJAX.
- PHP y ganchos para manejar datos.
Paso 2: Marcado HTML
Vamos a mostrar un botón en forma de corazón en la sección del pie de página de un artículo. Para ello, añadiremos marcado en el archivo content-single.php (dentro del tema Twenty Eleven).
1 |
<p class="post-like"> |
2 |
<a data-post_id="POST_ID" href="#"> |
3 |
<span class="qtip like" title="I like this article"></span> |
4 |
</a>
|
5 |
<span class="count">POST_LIKES_COUNT</span> |
6 |
</p>
|
Ten en cuenta que utilizamos meta atributos personalizados HTML5 para almacenar nuestros datos para que sea muy fácil de manejar con jQuery. Así que esto será generado por PHP, como veremos en el siguiente paso.
Paso 3: CSS3
Usaremos animaciones CSS3 para agregar interactividad visual y sprites CSS para reducir el número de imágenes externas.
1 |
article footer .post-like{ |
2 |
margin-top:1em |
3 |
}
|
4 |
|
5 |
article footer .like{ |
6 |
background:url(images/icons.png) no-repeat; |
7 |
width: 15px; |
8 |
height: 16px; |
9 |
display: block; |
10 |
float:left; |
11 |
margin-right: 4px; |
12 |
-moz-transition: all 0.2s ease-out 0.1s; |
13 |
-webkit-transition: all 0.2s ease-out 0.1s; |
14 |
-o-transition: all 0.2s ease-out 0.1s |
15 |
}
|
16 |
|
17 |
article footer .post-like a:hover .like{ |
18 |
background-position:-16px 0; |
19 |
}
|
20 |
|
21 |
article footer .voted .like, article footer .post-like.alreadyvoted{ |
22 |
background-position:-32px 0; |
23 |
}
|
En este punto, debería lucir como esto.


Paso 4: jQuery
Usaremos jQuery incorporado para manejar las peticiones AJAX. Al hacer clic, jQuery pasará algunos parámetros a nuestro controlador PHP y manejará la respuesta para mostrar información adecuada.
Así que vamos a crear un nuevo archivo llamado post-like.js y vamos a añadirlo a la carpeta js. Luego, ábrelo y agrega este código:
1 |
jQuery(document).ready(function() { |
2 |
|
3 |
jQuery(".post-like a").click(function(){ |
4 |
|
5 |
heart = jQuery(this); |
6 |
|
7 |
// Retrieve post ID from data attribute
|
8 |
post_id = heart.data("post_id"); |
9 |
|
10 |
// Ajax call
|
11 |
jQuery.ajax({ |
12 |
type: "post", |
13 |
url: ajax_var.url, |
14 |
data: "action=post-like&nonce="+ajax_var.nonce+"&post_like=&post_id="+post_id, |
15 |
success: function(count){ |
16 |
// If vote successful
|
17 |
if(count != "already") |
18 |
{
|
19 |
heart.addClass("voted"); |
20 |
heart.siblings(".count").text(count); |
21 |
}
|
22 |
}
|
23 |
});
|
24 |
|
25 |
return false; |
26 |
})
|
27 |
})
|
Explicaciones
En primer lugar, vamos a recuperar el ID de la publicación con el método de datos jQuery y luego vamos a pasarlo a nuestro controlador PHP. La variable ajax_var se crea de forma dinámica con PHP (veremos esto en la siguiente sección).
La mejor manera de usar AJAX dentro de WordPress es hacer llamadas a admin-ajax.php. Se encuentra en la carpeta wp-admin y puede vincular las funciones de devolución de llamada con ganchos. Vamos a ver cómo funciona.
Paso 5: PHP y ganchos (Hooks)
¿Cómo vamos a proceder? Vamos a vincular algunas funciones a los ganchos de WordPress y luego vamos a poner en cola nuestro script y añadiremos algunas variables JavaScript generadas con PHP para ser utilizadas por jQuery.
Hooks o Ganchos
Vamos a abrir el archivo functions.php y empezaremos a agregar nuestras funciones.
Primero lo primero, necesitamos vincular funciones a los ganchos de WordPress. Así que agrega estas dos líneas en tu archivo:
1 |
add_action('wp_ajax_nopriv_post-like', 'post_like'); |
2 |
add_action('wp_ajax_post-like', 'post_like'); |
El primer gancho es disparado cuando un usuario está conectado y el otro cuando no lo están. Mira más información sobre cómo implementar AJAX de la manera correcta aquí: 5 consejos para usar AJAX en WordPress.
Puedes ver la parte "post-like" del gancho, la cual es el parámetro de acción que usamos en el paso anterior con jQuery.
Ahora pondremos en cola nuestro script y declararemos nuestras variables:
1 |
wp_enqueue_script('like_post', get_template_directory_uri().'/js/post-like.js', array('jquery'), '1.0', true ); |
2 |
wp_localize_script('like_post', 'ajax_var', array( |
3 |
'url' => admin_url('admin-ajax.php'), |
4 |
'nonce' => wp_create_nonce('ajax-nonce') |
5 |
));
|
Aquí definimos dos parámetros importantes:
- URL: la dirección completa del URL a admin-ajax.php
- Nonce: Un hash de seguridad para prevenir ataques y errores.
Puedes utilizar esos parámetros con jQuery de esta manera: ajax_var.url y ajax_var.nonce.
"Usar los ganchos de WordPress y admin-ajax.php es la manera más segura de lidiar con AJAX".
Funciones
Añadamos la función post_like. Esto va a:
- Comprobar el nonce
- Recuperar la ID de la publicación, la IP del usuario y las publicaciones metas personalizadas
- Comprobar si el usuario ya ha votado o no
- Guardar datos (IP + conteo de votos) para la publicación actual
- Devolver el valor de recuento a jQuery
1 |
function post_like() |
2 |
{
|
3 |
// Check for nonce security
|
4 |
$nonce = $_POST['nonce']; |
5 |
|
6 |
if ( ! wp_verify_nonce( $nonce, 'ajax-nonce' ) ) |
7 |
die ( 'Busted!'); |
8 |
|
9 |
if(isset($_POST['post_like'])) |
10 |
{
|
11 |
// Retrieve user IP address
|
12 |
$ip = $_SERVER['REMOTE_ADDR']; |
13 |
$post_id = $_POST['post_id']; |
14 |
|
15 |
// Get voters'IPs for the current post
|
16 |
$meta_IP = get_post_meta($post_id, "voted_IP"); |
17 |
$voted_IP = $meta_IP[0]; |
18 |
|
19 |
if(!is_array($voted_IP)) |
20 |
$voted_IP = array(); |
21 |
|
22 |
// Get votes count for the current post
|
23 |
$meta_count = get_post_meta($post_id, "votes_count", true); |
24 |
|
25 |
// Use has already voted ?
|
26 |
if(!hasAlreadyVoted($post_id)) |
27 |
{
|
28 |
$voted_IP[$ip] = time(); |
29 |
|
30 |
// Save IP and increase votes count
|
31 |
update_post_meta($post_id, "voted_IP", $voted_IP); |
32 |
update_post_meta($post_id, "votes_count", ++$meta_count); |
33 |
|
34 |
// Display count (ie jQuery return value)
|
35 |
echo $meta_count; |
36 |
}
|
37 |
else
|
38 |
echo "already"; |
39 |
}
|
40 |
exit; |
41 |
}
|
Estamos guardando la IP del usuario y el tiempo actual en un post_meta y los votos se cuentan en otro. El tiempo nos ayudará a comprobar si el usuario puede volver a votar nuevamente después de un cierto tiempo transcurrido.
¿Podrías preguntar qué sucede cuando no se ha registrado ninguna votación actualmente? Bueno, WordPress nos ayuda una vez más aquí, porque update_post_meta comprueba si existe meta y lo crea si no (mira más información sobre esta función en el códice de WordPress).
Vamos a definir cuánto tiempo un usuario tiene que esperar antes de votar de nuevo (en minutos).
1 |
$timebeforerevote = 120; // = 2 hours |
Esta variable se puede almacenar en el panel de administración del tema por ejemplo, así que es fácil de editar.
Ahora agrega este código para comprobar si el usuario ya ha votado:
1 |
function hasAlreadyVoted($post_id) |
2 |
{
|
3 |
global $timebeforerevote; |
4 |
|
5 |
// Retrieve post votes IPs
|
6 |
$meta_IP = get_post_meta($post_id, "voted_IP"); |
7 |
$voted_IP = $meta_IP[0]; |
8 |
|
9 |
if(!is_array($voted_IP)) |
10 |
$voted_IP = array(); |
11 |
|
12 |
// Retrieve current user IP
|
13 |
$ip = $_SERVER['REMOTE_ADDR']; |
14 |
|
15 |
// If user has already voted
|
16 |
if(in_array($ip, array_keys($voted_IP))) |
17 |
{
|
18 |
$time = $voted_IP[$ip]; |
19 |
$now = time(); |
20 |
|
21 |
// Compare between current time and vote time
|
22 |
if(round(($now - $time) / 60) > $timebeforerevote) |
23 |
return false; |
24 |
|
25 |
return true; |
26 |
}
|
27 |
|
28 |
return false; |
29 |
}
|
"Siempre debes preguntarte si vale la pena usar un plugin y desacelerar WordPress en lugar de agregar algún código simple dentro de tu tema". Siempre que sea posible, la funcionalidad debe incluirse a través de complementos, no directamente en el functions.php del tema.
Nada demasiado complicado aquí, solo estamos comprobando si el usuario ya ha votado (es decir, si su dirección IP está entre la lista IP de los votos) y si se le permite votar de nuevo (es decir, el tiempo transcurrido desde que votó es mayor que $timebeforerevote).
Paso 6: Crea una función para generar el marcado HTML
Para obtener más control sobre cómo se muestran los votos y facilitar su actualización si se utiliza en distintos archivos, crearemos una función que genere el marcado. Si el usuario ya ha votado, no mostramos el corazón como un enlace para evitar llamadas AJAX inútiles.
1 |
function getPostLikeLink($post_id) |
2 |
{
|
3 |
$themename = "twentyeleven"; |
4 |
|
5 |
$vote_count = get_post_meta($post_id, "votes_count", true); |
6 |
|
7 |
$output = '<p class="post-like">'; |
8 |
if(hasAlreadyVoted($post_id)) |
9 |
$output .= ' <span title="'.__('I like this article', $themename).'" class="like alreadyvoted"></span>'; |
10 |
else
|
11 |
$output .= '<a href="#" data-post_id="'.$post_id.'"> |
12 |
<span title="'.__('I like this article', $themename).'"class="qtip like"></span> |
13 |
</a>'; |
14 |
$output .= '<span class="count">'.$vote_count.'</span></p>'; |
15 |
|
16 |
return $output; |
17 |
}
|
Puedes reemplazar el código insertado en el paso 2 por esta función:
1 |
<?php echo getPostLikeLink(get_the_ID());?> |
Paso 7: Ve más allá
Ahora los usuarios pueden votar en las publicaciones, es posible que desees recibir reacciones. Por ejemplo, podrías mostrar un top 10 de los artículos mejor votados.
Para ello, puedes utilizar el comando de consulta query_post con estas opciones:
1 |
query_posts('meta_key=votes_count&orderby=meta_value_num&order=DESC&posts_per_page=10'); |
Paso 7: Conclusión
¡Eso es! Ahora debes ser capaz de realizar un seguimiento de tus publicaciones de acuerdo a los votos de los usuarios y personalizar tanto el marcado y el CSS a tu conveniencia. Esta es sólo una forma de crear un sistema de puntuación simple, entre otros, así que no dudes en comentar este tutorial y dar tus comentarios. ¡Gracias por leer!



