Creando el sistema de valoración.
Tema de WordPress – Parte 3
Wow todo esto para llegar hasta aquí, la parte más divertida y a la vez mas difícil de esto, crear el sistema de valoración. Primeramente, debo aclarar que mi solución no necesariamente es la mejor, sin embargo, es la que considere más conveniente.
Empeze por el formulario, hacerlo no es dificil, a parte que en la web sobran los ejemplos de formularios con estrellas. Pero la parte complicada es integrar eso a WordPress. Se que pude haber hecho un plugin aparte pero queria que todo estuviera en el mismo tema. Adicionalmente no queria depender de plugins de terceros. Ya que era algo sencillo.
Hay que registrar el custom post meta en tu archivo functions. En mi caso decidi que todo se guardaria en una variable de tipo string. Una vez definido esto necesitare un endpoint para ingresar la informacion del rating sin la necesidad de recargar la pagina. Para esto recurrí a la api de WordPress.
**Acá Registre el endpoint**
$meta_args = [
'type' => 'string',
'single'=> false,
'show_in_rest' => true
];
register_post_meta('post','ngbt-rating',$meta_args);
function ngbt_api_rating_route(){
register_rest_route(
'ngbt',
'rating',
[
"methods" => "POST",
"callback" => "ngbt_post_rating"
]
);
}
add_action('rest_api_init','ngbt_api_rating_route');
Luego de definir tu endpoint, hay que crear el callback, la función que va a recoger la información de cuando el POST request en enviado a tu endpoint. Aca creas tu logica para guardar esa valoracion en la informacion de tu post.
**Esta es la función que guarda la información de la valoración**
function ngbt_post_rating($request){
try{
$message =[];
$found = false;
$rating_var = get_post_meta($request["post"],'ngbt-rating',true);
$data_to_push =[
"user_id" => $request["user_id"],
"rating" => $request["rating"]
];
if($rating_var){
$unserialized_rating = unserialize($rating_var);
foreach($unserialized_rating as $item){
if($item["user_id"] == $request["user_id"]){
$found = true;
array_push($message,["msg" => "already voted"]);
break;
}
}
if(!$found){
array_push($unserialized_rating,$data_to_push);
update_post_meta($request["post"],"ngbt-rating",serialize($unserialized_rating));
}
} else{
array_push($message,["msg" => "rating info updated"]);
update_post_meta($request["post"],"ngbt-rating",serialize([$data_to_push]));
}
if(sizeof($message)> 0){
array_push($message,["msg" => "rating info updated"]);
}
return $message;
}
catch(Exception $e){
error_log("Ha habido un error $e->getMessage()");
}
}
Creando el formulario del sistema de valoración
También hay que mostrar el rating de tu post así que para esto utilice el mismo formulario para enviar la valoración, y con un poquito de PHP hice que dependiendo del valor mostrara el checked. Utilizando un poco de JavaScript logramos no solo enviar el post una vez que la persona haga clic al formulario de valoración sino también que muestre un mensaje en caso de ya haberlo votado o en caso de error.
Acá creo el formulario para enviar la valoración. Cada uno tiene un valor que se envía dependiendo de la estrella en la que se haga click.
<form class="col-4 rating-box" id="rating-form">
<div class="rating-box-content">
<input id="radio1" type="radio" name="rating" value="5" <?php if($args["rating_data"]==5){echo 'checked';}?>><!--
--><label for="radio1">★</label><!--
--><input id="radio2" type="radio" name="rating" value="4" <?php if($args["rating_data"]==4){echo 'checked';}?>><!--
--><label for="radio2">★</label><!--
--><input id="radio3" type="radio" name="rating" value="3" <?php if($args["rating_data"]==3){echo 'checked';}?>><!--
--><label for="radio3">★</label><!--
--><input id="radio4" type="radio" name="rating" value="2" <?php if($args["rating_data"]==2){echo 'checked';}?>><!--
--><label for="radio4">★</label><!--
--><input id="radio5" type="radio" name="rating" value="1" <?php if($args["rating_data"]==1){echo 'checked';}?>><!--
--><label for="radio5">★</label>
</div>
<input type="text" name="user_id" id="" value="<?php echo $args["user_id"];?>" style="display:none">
<input type="text" name="post" id="" value="<?php echo $args["post_id"];?>" style="display:none">
</form>
Acá abajo esta un CSS que me robé, créditos a su respectivo autor (al momento de redactar esto no lo pude encontrar), este me ayudo bastante a simplificar como se iluminarían las estrellas al momento de posicionarse sobre ella.
.rating-box-content label{
color:grey;
}
.rating-box-content input[type = "radio"]{
display:none;
}
.rating-box-content{
text-align: left;
}
.rating-box-content{
direction: rtl;
unicode-bidi: bidi-override;
}
.rating-box-content label:hover, .rating-box-content label:hover ~ label, input[type="radio"]:checked ~ label{
color:orange;
}
Aca se puede ver como en el archivo functions.php se llama a este template part con la información que necesita. En este caso, el ID de quien esta viendo el post, el post id y la valoración
function get_rating_template_part(){
/*
render template with rating info
*/
$rating_var = get_post_meta(get_the_ID(),'ngbt-rating',true);
$data = [
"user_id" =>get_current_user_id(),
"post_id" =>get_the_ID(),
"rating_data" =>calculate_rating($rating_var)
];
get_template_part('assets/template-parts/content','ratingbox',$data);
}
Para terminar en el front page que diseñe le cree la funcionalidad que en una sección dedicada a los top posts me incluyera a cualquier post que tenga una valoración de 4 en adelante. Se que es extenso pero disfrute mucho hacerlo.
Con esto concluyo la creación del tema (por ahora), este tema está disponible aquí. Acá se encuentra la primera entrega y acá les dejo la segunda entrega.