Pregunta sobre wp_ajax() sin usar wp_enqueue_script
Hola chicos,
Situación extraña... Estoy intentando usar wp_ajax() por primera vez. Normalmente uso una petición AJAX normal con jQuery, pero en este caso me da muchos errores y pensé en probar wp_ajax().
¡Pero no lo entiendo!
El siguiente fragmento de código...
// incrustar el archivo JavaScript que hace la petición AJAX
wp_enqueue_script( 'my-ajax-request', plugin_dir_url( __FILE__ ) . 'js/ajax.js' );
// declarar la URL al archivo que maneja la petición AJAX (wp-admin/admin-ajax.php)
wp_localize_script( 'my-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
resulta en...
<script type="text/javascript" src="http://example.com/wordpress/wp-content/plugins/myajax/js/ajax.js"></script>
<script type="text/javascript">
/* <![CDATA[ */
var MyAjax = {
ajaxurl: "http://example.com/wordpress/wp-admin/admin-ajax.php"
};
/* ]]> */
Sin embargo, no tengo un plugin o algo que deba usar esto, pero toda mi página necesita hacer esta petición AJAX. Por lo tanto, la primera línea con wp_enqueue_script()
no tiene sentido. No necesito cargar un archivo JS específico para esto porque ya tengo mi archivo script.js
incrustado manualmente en mi sección <head>
. Aquí es donde se dispara la petición AJAX. Pero si omito esta línea (//wp_enqueue_script()...
), la segunda parte no funciona.
Así que no se imprimirá:
<script type="text/javascript">
/* <![CDATA[ */
var MyAjax = {
ajaxurl: "http://example.com/wordpress/wp-admin/admin-ajax.php"
};
/* ]]> */
en la sección <head>
de mi página. ¿Qué estoy entendiendo mal?
Realmente necesito poder hacer una petición AJAX desde mi archivo script.js normal.
¿Alguna idea?
Actualización:
mi archivo script.js (incrustado manualmente en mi <head>
) debería llamar a una petición AJAX:
var response;
$.post(
// ver consejo #1 sobre cómo declarar variables globales en JavaScript
MyAjax.ajaxurl,
{
// aquí declaramos los parámetros para enviar con la petición
// esto significa que se dispararán los siguientes hooks:
// wp_ajax_nopriv_myajax-submit y wp_ajax_myajax-submit
action: 'wp_ajax_nopriv_searchmap',
},
function(response) {
$sr.html(response);
La función en mi archivo functions.php que quiero llamar se ve así:
// incrustar el archivo JavaScript que hace la petición AJAX
wp_enqueue_script( 'my-ajax-request', plugin_dir_url( __FILE__ ) . 'js/ajax.js' );
// declarar la URL al archivo que maneja la petición AJAX (wp-admin/admin-ajax.php)
wp_localize_script( 'my-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
// este hook se dispara si el visitante no está logueado
if (isset($_GET['action'])) {
do_action( 'wp_ajax_nopriv_' . $_GET['action'] );
}
// si está logueado:
if (isset($_POST['action'])) {
do_action( 'wp_ajax_' . $_POST['action'] );
}
if(is_admin()) {
add_action( 'wp_ajax_searchmap', 'my_searchmap_function' );
} else {
add_action( 'wp_ajax_nopriv_searchmap', 'my_searchmap_function' );
}
function my_searchmap_function() {
// Iniciar buffer de salida
ob_start();
?>
<div>
<h3>Páginas</h3>
<ul>
<?php wp_list_pages('title_li=&depth=0&exclude='); ?>
</ul>
<h3>Entradas</h3>
<?php $first = 0;?>
<ul>
<?php
$myposts = get_posts('numberposts=-1&offset=$first');
foreach($myposts as $post) :
?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
</ul>
<h3>Categorías</h3>
<ul>
<?php wp_list_categories('title_li=&orderby=name'); ?>
</ul>
</div>
<?php
$output = ob_get_contents();
// Detener buffer de salida
ob_end_clean();
$response = json_encode($output);
// respuesta de salida
header( "Content-Type: application/json" );
echo $response;
// IMPORTANTE: no olvides hacer "exit"
exit;
}
¿Qué estoy entendiendo mal aquí? Simplemente quiero poder solicitar datos via AJAX desde mi archivo JavaScript normal. Necesito procesar el HTML que devuelve en mi archivo JavaScript.
¿Alguna idea de lo que estoy haciendo mal o mejor, qué debo hacer para que esto funcione?

Bien, primero déjame desglosarlo un poco para que entiendas el propósito de estas funciones.
-
Descripción:
Una forma segura de agregar scripts JavaScript a una página generada por WordPress. Básicamente, incluye el script si no se ha incluido ya, y carga el que viene con WordPress. -
Descripción:
Localiza un script, pero solo si el script ya ha sido agregado. También se puede usar para incluir datos arbitrarios de JavaScript en una página.
Cuando localizas un script, lo que estás haciendo es configurar una acción que imprime variables JavaScript en la página, pero estas variables están vinculadas al script que las registras, es el primer parámetro que pasas a wp_localize_script
y también se conoce como el handle del script.
wp_enqueue_script
es para encolar un archivo JavaScript, y wp_localize_script
está diseñado para acompañar scripts cargados a través del sistema de encolamiento. No puedes localizar nada, así que si no estás encolando, wp_localize_script
no te será útil aquí.
Normalmente usarías los dos de esta manera...
$myvars = array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'somevar1' => $somevar_from_somewhere,
'somevar2' => $somevar_from_elsewhere
);
wp_enqueue_script( 'my-ajax-request', plugins_url( '/path/to/somefile.js', __FILE__ ) );
wp_localize_script( 'my-ajax-request', 'MyAjax', $myvars );
Lo cual produce el siguiente resultado en tu página...
<script type="text/javascript" src="path/to/somefile.js"></script>
<script type="text/javascript">
/* <![CDATA[ */
var MyAjax = {
ajaxurl: "http://example.com/wordpress/wp-admin/admin-ajax.php",
somevar1: "somevalue",
somevar2: "someothervalue"
};
/* ]]> */
</script>
Que luego puedes referenciar en tu script, por ejemplo:
jQuery(document).ready( function($) {
alert( MyAjax.somevar1 ); // Muestra "somevalue"
alert( MyAjax.somevar2 ); // Muestra "someothervalue"
});
Juntando todo esto, tu código podría verse algo así...
// Configurar la callback AJAX para la acción "searchmap"
add_action( 'wp_ajax_searchmap', 'my_searchmap_function' );
add_action( 'wp_ajax_nopriv_searchmap', 'my_searchmap_function' );
// La función de callback para la acción "searchmap"
function my_searchmap_function() {
$myposts = get_posts('numberposts=-1&offset=$first');
?>
<div>
<h3>Páginas</h3>
<ul>
<?php wp_list_pages('title_li=&depth=0&exclude='); ?>
</ul>
<h3>Entradas</h3>
<ul>
<?php foreach( $myposts as $post ) : setup_postdata( $post ); ?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
<?php wp_reset_postdata(); ?>
</ul>
<h3>Categorías</h3>
<ul>
<?php wp_list_categories('title_li=&orderby=name'); ?>
</ul>
</div>
<?php
die;
}
El JavaScript... (asumiendo que fue encolado y localizado)
jQuery(document).ready(function($) {
$('a.myajax').click(function(){
var data = {
action: 'searchmap' // <--- este es el nombre correcto de la acción
};
$.post( MyAjax.ajaxurl, data, function(response) {
$('#myresult').html(response);
});
return false;
});
});
Y luego el HTML necesario en la página para activar la acción...
<a class="myajax" href="#">Haz clic para obtener contenido AJAX</a>
<div id="myresult"></div>
Respuesta Real
Con respecto a necesitar hacer algo propio y obtener variables impresas para tu script, sugeriría hacer algo como esto...
add_action( 'wp_head', 'my_js_vars', 1000 );
function my_js_vars() {
// Si no es una página específica, detenerse aquí
if( !is_page( 'my-page-with-ajax' ) )
return;
?>
<script type="text/javascript">
/* <![CDATA[ */
var MyAjax = {
ajaxurl: '<?php admin_url('admin-ajax.php'); ?>',
somevar: 'somevalue',
someothervar: 'someothervalue'
};
/* ]]> */
</script>
<?php
/*
NOTA:
Asegúrate de no dejar una coma después del último elemento
en el array de JS, de lo contrario IE (Internet Explorer) tendrá problemas con el JS.
*/
}
Dejé el código que publiqué anteriormente para beneficio de otros lectores.

gracias. Entonces, ¿cómo puedo llamar a una función dentro de mi function.php a través de ajax? Actualicé mi pregunta. ¡Realmente agradecería tu ayuda con eso!

gracias, ¿qué pasa con las líneas wp_enqueue_script();
y wp_localize_script()
? ¿Tengo que mantenerlas? ¿Debería wp_enqueue_script() apuntar al mismo directorio que mi archivo js normal (donde quiero llamar al ajax)? Porque de lo contrario no puedo usar MyAjax.ajaxurl, { action : 'wp_ajax_nopriv_searchmap', }
para llamar al script - porque MyAjax no existe si no uso lo de localize_script? ¿Cómo se vería mi javascript para llamar a esta función?

@mathiregister: así es, tienes que mantenerlos, si no usas wp_enqueue_script();
para encolarlo de la forma correcta en WordPress entonces no podrás usar wp_localize_script()
ya que ese script no es conocido por WordPress, podrías imprimir el script y definir la url ajax en php pero eso sería una mala práctica. Y por último, tu action: 'wp_ajax_nopriv_searchmap'
debería ser action: 'searchmap'
, el prefijo del hook ya lo hace WordPress por ti.

gracias, casi lo tengo funcionando como quiero. Última pregunta: todavía no entiendo bien lo de localize_script(). Sin esto no tengo la variable MyAjax configurada en el head. Sin embargo, para que wp_localize_script() funcione necesito configurar wp_enqueue_script(), ¡de lo contrario la variable tampoco se configurará!

Además, obtengo este error en mi consola en cada 4ta o 5ta llamada POST http://oberperfuss.at/wp-admin/admin-ajax.php undefined (undefined)
¿Alguna idea de qué podría causarlo?

Toma el código JS que publiqué, colócalo en tu archivo JS, encolalo y elimina el JS que estás poniendo directamente en el head. Añade esto en la página que carga el archivo JS.. <a href="#" class="myajax">Click me</a><div id="myresult"></div>
y luego carga la página y haz clic en el enlace (informa qué sucede).

¡Ya funciona! Solo necesito saber por qué tengo que encolarlo, porque no quiero hacerlo. Estoy usando el proyecto head.js para cargar todos mis scripts y que mi página cargue rápido. Solo necesito encontrar una manera de incluir admin-ajax.js sin usar wp_enqueue_script(). Porque con wp_enqueue_script() la línea wp_localize_script() no crea la variable MyAjax.

Este tutorial en el codex ofrece una visión general sencilla del proceso:
http://codex.wordpress.org/AJAX_in_Plugins
Ten en cuenta que la variable ajaxurl
ya está definida por el núcleo de WP, pero solo en el área de administración. Para agregarla en el front-end, usa:
<?php
function pluginname_ajaxurl() {
?>
<script type="text/javascript">
var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
</script>
<?php
}
add_action('wp_head','pluginname_ajaxurl');

Ah, pero hay un problema, no siempre está definido, me pasó cuando intenté usarlo... Al menos no siempre estaba disponible en mis pruebas, y no para usuarios invitados.

Otto con un fragmento de código sobre cómo definir la variable en el frontend - http://wordpress.org/support/topic/ajaxurl-is-not-defined?replies=4#post-1989445
