Problema con wp_ajax() senza usare wp_enqueue_script?

28 mar 2011, 15:05:59
Visualizzazioni: 13.9K
Voti: 1

ragazzi, situazione strana... sto provando a usare wp_ajax() per la prima volta. Normalmente uso una normale richiesta jQuery ajax ma in questo caso ho molti bug quindi ho pensato di provare wp_ajax().

Ma non capisco!

Questo pezzo di codice...

// incorpora il file javascript che effettua la richiesta AJAX
wp_enqueue_script( 'my-ajax-request', plugin_dir_url( __FILE__ ) . 'js/ajax.js' );

// dichiara l'URL del file che gestisce la richiesta AJAX (wp-admin/admin-ajax.php)
wp_localize_script( 'my-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );

risulta in...

<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"
};
/* ]]> */

Però io non ho un plugin o altro che dovrebbe usare questo, ma tutta la mia pagina deve fare questa richiesta ajax. Quindi la prima riga con wp_enqueue_script() non ha senso. Non ho bisogno di caricare un file js specifico perché ho già il mio intero file script.js incorporato manualmente nella sezione <head>. È qui che viene lanciata la richiesta ajax. Però se tolgo questa riga (//wp_enqueue_script()...) la seconda parte non funziona.

Quindi non verrà stampato:

<script type="text/javascript">
/* <![CDATA[ */
var MyAjax = {
    ajaxurl: "http://example.com/wordpress/wp-admin/admin-ajax.php"
};
/* ]]> */

nella sezione della mia pagina. Cosa sto sbagliando? Ho davvero bisogno di poter lanciare una richiesta ajax dal mio normale file script.js.

Qualche idea?

aggiornamento: il mio file script.js (incorporato manualmente nel mio <head>) dovrebbe chiamare una richiesta ajax:

var response;
            $.post(
                // vedi suggerimento #1 per come dichiariamo le variabili javascript globali
                MyAjax.ajaxurl,
                {
                    // qui dichiariamo i parametri da inviare con la richiesta
                    // questo significa che verranno attivati i seguenti hook:
                    // wp_ajax_nopriv_myajax-submit e wp_ajax_myajax-submit
                    action : 'wp_ajax_nopriv_searchmap',
                },
                function( response ) {
                    $sr.html(response);

La funzione nel mio file functions.php che voglio chiamare è questa:

// incorpora il file javascript che effettua la richiesta AJAX
wp_enqueue_script( 'my-ajax-request', plugin_dir_url( __FILE__ ) . 'js/ajax.js' );

// dichiara l'URL del file che gestisce la richiesta AJAX (wp-admin/admin-ajax.php)
wp_localize_script( 'my-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );

// questo hook viene attivato se l'utente corrente non è loggato
if (isset($_GET['action'])) {
    do_action( 'wp_ajax_nopriv_' . $_GET['action'] );
}
// se loggato:
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() {

// Avvia output buffer
ob_start();
?>
div>
    <h3>Pagine</h3>
        <ul>
            <?php wp_list_pages('title_li=&depth=0&exclude='); ?>
        </ul>
    <h3>Articoli</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>Categorie</h3>
        <ul>
            <?php wp_list_categories('title_li=&orderby=name'); ?>
        </ul>
</div>  
<?php 

    $output = ob_get_contents();

    // Termina output buffer
    ob_end_clean();
    $response = json_encode($output);

    // output della risposta
    header( "Content-Type: application/json" );
    echo $response;

    // IMPORTANTE: non dimenticare di fare "exit"
    exit;
}

Cosa non sto capendo? Voglio semplicemente poter richiedere dati via ajax dal mio normale file javascript. Devo processare l'html che ritorna nel mio file javascript.

Qualche idea su cosa sto sbagliando o meglio, cosa devo fare per far funzionare tutto?

0
Tutte le risposte alla domanda 2
10
10

Ok, iniziamo con una piccola suddivisione per comprendere meglio lo scopo di queste funzioni.

  • wp_enqueue_script()

    Descrizione:
    Un modo sicuro per aggiungere javascript alle pagine generate da WordPress. In sostanza, include lo script se non è già stato incluso e carica quello fornito da WordPress.

  • wp_localize_script()

    Descrizione:
    Localizza uno script, ma solo se lo script è già stato aggiunto. Può anche essere utilizzato per includere dati Javascript arbitrari in una pagina.

Quando localizzi uno script, tutto quello che stai facendo è impostare un'azione che stampa variabili Javascript nella pagina, ma queste variabili sono legate allo script con cui le registri, è il primo parametro che passi a wp_localize_script ed è anche conosciuto come handle dello script.

wp_enqueue_script serve per accodare un file javascript, mentre wp_localize_script è progettato per accompagnare gli script caricati tramite il sistema di enqueue. Non puoi localizzare nulla, quindi se non stai usando enqueue, wp_localize_script non ti sarà utile qui.

Tipicamente utilizzeresti le due funzioni in questo modo...

$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 );

Che poi produce il seguente output nella tua pagina...

<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>

Che puoi poi referenziare nel tuo script, ad esempio:

jQuery(document).ready( function($) {

    alert( MyAjax.somevar1 ); // Produce "somevalue"
    alert( MyAjax.somevar2 ); // Produce "someothervalue"

});

Mettendo tutto insieme, il tuo codice potrebbe essere qualcosa del genere...

// Configura la callback ajax per l'azione "searchmap" 
add_action( 'wp_ajax_searchmap', 'my_searchmap_function' );
add_action( 'wp_ajax_nopriv_searchmap', 'my_searchmap_function' );

// La funzione di callback per l'azione "searchmap"
function my_searchmap_function() {
    $myposts = get_posts('numberposts=-1&offset=$first');
?>
<div> 
    <h3>Pagine</h3>
    <ul>
        <?php wp_list_pages('title_li=&depth=0&exclude='); ?>
    </ul>

    <h3>Articoli</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>Categorie</h3>
    <ul>
    <?php wp_list_categories('title_li=&orderby=name'); ?>
    </ul>
</div>  
<?php 
    die;
}

Il JS .. (supponendo che sia stato accodato e localizzato)

jQuery(document).ready(function($) {
    $('a.myajax').click(function(){
        var data = {
            action: 'searchmap' // <--- questo è il nome corretto dell'azione
        };
        $.post( MyAjax.ajaxurl, data, function(response) {
            $('#myresult').html(response);
        });
        return false;
    });
});

E poi l'HTML effettivo necessario nella pagina per attivare l'azione...

<a class="myajax" href="#">Cliccami per recuperare contenuti via ajax</a>
<div id="myresult"></div>

Risposta Effettiva

Per quanto riguarda la necessità di fare le tue cose e ottenere variabili stampate per il tuo script, suggerirei di fare qualcosa del genere...

add_action( 'wp_head', 'my_js_vars', 1000 );

function my_js_vars() {

    // Se non è una pagina specifica, fermati qui
    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: 
       Assicurati di non lasciare una virgola dopo l'ultimo elemento 
       nell'array JS, altrimenti IE (Internet Explorer) avrà problemi con il JS.
    */
}

Ho lasciato il codice che ho postato in precedenza per il bene di chi legge.

28 mar 2011 15:48:57
Commenti

grazie. quindi come posso chiamare una funzione all'interno del mio functions.php via ajax? Ho aggiornato la mia domanda. Apprezzerei davvero il tuo aiuto con questo!

mathiregister mathiregister
28 mar 2011 15:57:13

Risposta aggiornata, vedi sopra. :)

t31os t31os
28 mar 2011 16:09:13

grazie, invece per le righe wp_enqueue_script(); e wp_localize_script()? Devo mantenerle? wp_enqueue_script() dovrebbe puntare alla stessa directory del mio file js normale (dove voglio chiamare l'ajax)? Perché altrimenti non posso usare MyAjax.ajaxurl, { action : 'wp_ajax_nopriv_searchmap', } per chiamare lo script - dato che MyAjax non esiste se non uso la cosa del localize_script? Come sarebbe il mio javascript per chiamare questa funzione?

mathiregister mathiregister
28 mar 2011 16:16:24

@mathiregister: esatto, devi mantenerli, se non usi p_enqueue_script(); per accodarlo nel modo WordPress allora non puoi usare wp_localize_script() poiché quello script non è noto a WordPress, puoi stampare lo script e definire l'URL ajax in php ma sarebbe una cattiva pratica. E infine il tuo action : 'wp_ajax_nopriv_searchmap' dovrebbe essere action : 'searchmap' il prefisso dell'hook viene gestito per te.

Bainternet Bainternet
28 mar 2011 16:49:32

@mathiregister - Ho aggiornato di nuovo la mia risposta per te.

t31os t31os
28 mar 2011 16:56:51

grazie, ho quasi fatto funzionare tutto come volevo. Ultima domanda però: ancora non capisco la questione con localize_script()? Senza di esso non ho la variabile MyAjax impostata nel mio head. Tuttavia, per far funzionare wp_localize_script() devo impostare wp_enqueue_script() altrimenti neanche la variabile verrà impostata!

mathiregister mathiregister
28 mar 2011 17:32:50

Inoltre ricevo questo errore nella console ogni 4 o 5 chiamate POST http://oberperfuss.at/wp-admin/admin-ajax.php undefined (undefined) Hai idea di cosa potrebbe causarlo?

mathiregister mathiregister
28 mar 2011 17:33:30

Prendi il codice JS che ho postato, inseriscilo nel tuo file JS, mettilo in coda ed elimina il JS che stai inserendo direttamente nell'head. Aggiungi questo nella pagina che carica il file JS.. <a href="#" class="myajax">Cliccami</a><div id="myresult"></div> e poi carica la pagina e clicca sul link (fammi sapere cosa succede).

t31os t31os
28 mar 2011 17:35:54

Funziona già! Ho solo bisogno di capire perché devo metterlo in coda, perché non voglio farlo. Sto usando il progetto head.js per caricare tutti i miei script così la mia pagina carica velocemente. Ho solo bisogno di trovare un modo per includere admin-ajax.js senza usare wp_enqueue_script(). Perché con wp_enqueue_script() la riga wp_localize_script() non crea la variabile MyAjax.

mathiregister mathiregister
28 mar 2011 19:08:04

Se non stai accodando uno script, smetti di usare la funzione localize script, dovrai inserire manualmente le tue variabili nell'intestazione del documento, praticamente emulando ciò che fa wp_localize_script..

t31os t31os
29 mar 2011 00:41:54
Mostra i restanti 5 commenti
3

Questo tutorial nel codex fornisce una panoramica chiara del processo:

http://codex.wordpress.org/AJAX_in_Plugins

Nota che la variabile ajaxurl è già definita dal core di WordPress, ma solo nell'area di amministrazione. Per aggiungerla nel front-end, utilizza:

<?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');
28 mar 2011 16:55:43
Commenti

Ah, ma c'è un inghippo, non è sempre definito, ci sono cascato quando ho provato a usarlo... Almeno non era sempre disponibile nei miei test, e non per gli utenti ospiti.

t31os t31os
28 mar 2011 17:32:38

Infatti, ho aggiunto una precisazione.

scribu scribu
28 mar 2011 19:48:23

Otto con uno snippet di codice su come definire la variabile nel frontend - http://wordpress.org/support/topic/ajaxurl-is-not-defined?replies=4#post-1989445

Mario Peshev Mario Peshev
7 ott 2012 17:31:59