Cómo pasar una variable de JavaScript a PHP en un widget de WordPress
Pasé mucho tiempo buscando una solución donde pueda pasar el valor de una variable JavaScript a una variable PHP en el mismo archivo, misma función (Widget de WordPress, función de formulario). ¿Existe una buena manera, a partir del 2017, de hacer esto?
Probé este método a continuación. Aunque la parte de Ajax muestra el mensaje de éxito, la parte PHP falla.
repeat.php
<?php
echo $_POST['examplePHP']; //aquí causará índice no definido
?>
<script>
jQuery(document).ready(function($){
var exampleJS = "¡Hola!";
$.ajax({
url: ajaxurl, //Intenté con 'repeat.php' en lugar de ajaxurl, pero no funciona.
type: 'POST',
data: {
examplePHP: exampleJS
},
success: function( response){
console.log("¡Éxito!");
},
error: function(error){
console.log("error");
}
});
});
</script>

Encontré una forma sencilla de pasar una variable de JavaScript a una variable PHP. Ten en cuenta que este método funciona en la versión 4.7.2 de WordPress, y específicamente solo en Widgets. Escribí muchos comentarios para intentar explicar lo que hace cada línea. Si tienes una mejor solución, ¡compártela con nosotros!
Solución:
- Crea un campo de entrada oculto para almacenar el valor de JavaScript que deseas pasar.
- Accede a ese campo de entrada oculto y asigna su valor a una variable PHP.
Demo del Widget:
Creé un widget de demostración que añade la palabra "TE AMO" según la cantidad de veces que presiones el botón "Añadir TE AMO".
Nota que dejé visible el campo oculto para una mejor comprensión.
Puedes cambiar
type="text"
atype="hidden"
para ocultarlo.Este demo solo se enfoca en la función
form
del widget.Asegúrate de hacer clic en el botón Guardar, de lo contrario, el valor del campo de entrada oculto no se guardará en el widget.
Captura de pantalla del Widget Demo:
Código fuente:
wp-text-repeater.php
<?php
/**
* Plugin Name: WP Text Repeater
**/
class wp_text_repeater extends WP_Widget {
/**
* Configura el nombre y descripción del widget
*/
public function __construct() {
$widget_ops = array(
'classname' => 'wp_text_repeater',
'description' => 'Widget que imprime TE AMO repetidamente según los clics del botón',
);
parent::__construct( 'wp_text_repeater', 'Widget Repetidor de Texto WP', $widget_ops );
}
/**
* Muestra el contenido del widget
*
* @param array $args
* @param array $instance
*/
public function widget( $args, $instance ) {
// muestra el contenido del widget
$wp_text_repeater_button = ! empty( $instance['wp_text_repeater_button'] ) ? $instance['wp_text_repeater_button'] : '';
$wp_text_repeater_appendee = ! empty( $instance['wp_text_repeater_appendee'] ) ? $instance['wp_text_repeater_appendee'] : '';
$wp_text_repeater_hidden = ! empty( $instance['wp_text_repeater_hidden'] ) ? $instance['wp_text_repeater_hidden'] : '';
}
/**
* Muestra el formulario de opciones en el admin
*
* @param array $instance Las opciones del widget
*/
public function form( $instance ) {
// muestra el formulario de opciones en el admin
$instance = wp_parse_args( (array) $instance, array( 'wp_text_repeater_button' => '', 'wp_text_repeater_appendee' => '', 'wp_text_repeater_hidden' => ''));
$wp_text_repeater_button = $instance['wp_text_repeater_button'];
$wp_text_repeater_appendee = $instance['wp_text_repeater_appendee'];
$wp_text_repeater_hidden = $instance['wp_text_repeater_hidden'];
$tempHidden = 'wp_text_repeater_hidden';
?>
<!-- Campo oculto que almacena el número de veces que el usuario presiona el botón -->
<input
class="widefat"
id="<?php echo $this->get_field_id($tempHidden); ?>"
name="<?php echo $this->get_field_name($tempHidden); ?>"
type="text"
value="<?php echo esc_attr($$tempHidden);?>"/>
<?php
$max = 0; //Número de veces que el usuario presiona el botón
//Si el campo oculto de JavaScript tiene valor, asigna $max a ese valor.
//Este condicional sincroniza JavaScript con PHP.
if(strlen($$tempHidden) > 0){
$max = intval($$tempHidden);
}
$counter = 0;
while($counter < $max){ //Bucle según las veces que el usuario presiona el botón
?>
<p>TE AMO!</p>
<?php
$counter++;
}
$id_prefix = $this->get_field_id(''); //Obtiene el prefijo del ID del widget.
?>
<!-- Aquí puedes añadir todo tu contenido -->
<span id="<?php echo $this->get_field_id('wp_text_repeater_appendee')?>"></span>
<!-- Botón que llama a la función jQuery para añadir "TE AMO" -->
<input style="background-color: #08a538; color:white; height: 27px;"
class="button widefat"
type="button"
id="<?php echo $this->get_field_id('wp_text_repeater_button'); ?>"
value="Añadir TE AMO"
onclick="text_repeater.addLove('<?php echo $this->id;?>', '<?php echo $id_prefix;?>'); return false;"
/>
<script>
jQuery(document).ready(function($){
var preIndexID;
var numberOfLove = <?php echo $max; ?>; //Obtiene el valor de PHP para sincronizar front-end y back-end.
text_repeater = {
addLove : function(widget_id, widget_id_string){
preIndexID = widget_id_string; //Obtiene el prefijo correcto del widget.
numberOfLove++;
numberOfLove = numberOfLove.toString(); //Convierte a string para el campo oculto.
$("#" + preIndexID + "wp_text_repeater_hidden").val(numberOfLove); //Cambia el valor del campo oculto.
$("#" + preIndexID + "wp_text_repeater_appendee").append('<p>TE AMO!</p>'); //Actualiza en vivo el front-end con "TE AMO".
}
}
});
</script>
<?php
}
/**
* Procesa las opciones del widget al guardar
*
* @param array $new_instance Las nuevas opciones
* @param array $old_instance Las opciones anteriores
*/
public function update( $new_instance, $old_instance ) {
// procesa las opciones del widget para guardar
$instance = $old_instance;
$instance['wp_text_repeater_button'] = sanitize_text_field($new_instance['wp_text_repeater_button']);
$instance['wp_text_repeater_appendee'] = sanitize_text_field($new_instance['wp_text_repeater_appendee']);
$instance['wp_text_repeater_hidden'] = sanitize_text_field($new_instance['wp_text_repeater_hidden']);
return $instance;
}
}
// Registra el widget wp_text_repeater
function register_wp_text_repeater_widget() {
register_widget( 'wp_text_repeater' );
}
add_action( 'widgets_init', 'register_wp_text_repeater_widget' );

Por favor recuerda que el código se ejecuta de arriba hacia abajo.
De esta manera no puedes 'obtener' la variable POST antes de enviarla mediante ajax.
Algo que sí funcionaría con tu configuración:
<?php
if(isset($_POST['examplePHP'])){ //verifica si $_POST['examplePHP'] existe
echo $_POST['examplePHP']; // muestra los datos
die(); // detiene la ejecución del script.
}
?>
<script>
jQuery(document).ready(function($){
var exampleJS = "¡hola!";
$.ajax({
url: window.location, //window.location apunta a la URL actual. se necesita cambio.
type: 'POST',
data: {
examplePHP: exampleJS
},
success: function( response){
console.log("¡Éxito! Mis datos post son: "+response);
},
error: function(error){
console.log("error");
}
});
});
</script>
Primero verificamos si la variable POST existe con isset()
. Si existe, mostramos el contenido de 'examplePHP' y luego detenemos la ejecución del script con die();
.
Si no hay una variable POST disponible, significa que alguien acaba de cargar la página. Entonces no mostramos nada y simplemente continuamos con el resto de la página.
He añadido window.location
que es la URL actual. Y la variable response
devuelve el eco.
Ya que esto es WordPress Stack Exchange, te recomendaría que uses WordPress Ajax. ¡Puedes leer más sobre esto en la página del Codex!
