Perché il 'do_shortcode' di un plugin potrebbe non funzionare in una richiesta AJAX?

25 mag 2012, 20:02:18
Visualizzazioni: 19K
Voti: 9

tl;dr: Il shortcode di Contact Form 7 non funziona in una richiesta AJAX quando chiamato con do_shortcode

functions.php

add_action('wp_ajax_ps_get_survey_form', 'ps_get_survey_form');
add_action('wp_ajax_nopriv_ps_get_survey_form', 'ps_get_survey_form');

function ps_get_survey_form() {
    echo do_shortcode( '[contact-form-7 id="397" title="Contact form 1"]' );
    die();
}

script.js

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

    $('#survey-modal').fancybox({
        href: ajaxurl,
        ajax: {
            type : "POST",
            data : {action: 'ps_get_survey_form'}
        }
    });
});

Tuttavia,

echo do_shortcode( '[contact-form-7 id="397" title="Contact form 1"]' )

restituisce la stringa del shortcode stessa. Funziona correttamente se inserito in un template.

Per quanto ci abbia provato (cose assurde come avvolgerlo in un post/applicare il filtro the_content, attivare manualmente varie azioni a cui CF7 si aggancia, ecc.) si rifiuta di trasformarsi in un form.

Come posso debuggar questo problema?

EDIT

@Kaiser suggerisce saggiamente che potrei non avere accesso a do_shortcode. Ho provato a verificarlo, con il seguente risultato:

function ps_get_survey_form() {

    //include( ABSPATH . 'wp-includes/shortcodes.php' ); 
    //Causa errore fatale: non è possibile ridefinire add_shortcode

    if ( function_exists( 'do_shortcode ' ) )  {
        echo "do_shortcode esiste";
    } else {
        echo "do_shortcode non esiste";  // viene stampato questo
    }

    do_shortcode( 'foo' );      // fallisce silenziosamente, anche se apparentemente la funzione non è stata definita
    //foo();                    // Causa errore fatale come previsto

    //echo do_shortcode( '[contact-form-7 id="397" title="contact form 1"]' );
    die();
}
7
Commenti

Forse perché la funzione dello shortcode non è ancora stata registrata a quel punto?

onetrickpony onetrickpony
25 mag 2012 20:10:15

@OneTrickPony - Concordo che sembra probabile. La domanda è, come posso fare in modo che venga registrata (se capisci cosa intendo)?

djb djb
26 mag 2012 13:56:05

Gestisci semplicemente la richiesta ajax da solo nell'azione "wp" o "init". L'admin-ajax di WP è stato progettato per essere utilizzato nell'area di amministrazione comunque

onetrickpony onetrickpony
26 mag 2012 15:05:00

@OneTrickPony, grazie. funziona. posterò il codice funzionante sopra per completezza.

djb djb
26 mag 2012 16:54:57

L'ultima volta che ho controllato Contact Form 7, non utilizzavano l'API degli shortcode integrata, optando invece per crearne una propria. Vale la pena verificare.

chrisguitarguy chrisguitarguy
31 lug 2012 21:47:41

Non capisco cosa succeda nella chiamata ajax. Perché se provo funtion_exists come sopra per get_option() in questo modo if(function_exists('get_option')){echo 'exist';}else{echo 'not exist';} restituisce not exist ma quando semplicemente echo ad esempio il nome del blog get_option('blogname'); stampa il nome del blog. Posso vederlo nella risposta ajax. Se la funzione non esiste, come può funzionare? Anche do_shortcode() funziona quando provo a ottenere il titolo del sito. Ma quando provo a ottenere il titolo del post non stampa nulla. Quale potrebbe essere il problema? @onetrickpony

sun sun
27 mag 2014 16:04:35

@sun Per favore leggi [chiedi] e fai la tua domanda.

kaiser kaiser
27 mag 2014 16:07:44
Mostra i restanti 2 commenti
Tutte le risposte alla domanda 2
2

WP Ajax esegue chiamate sia pubbliche che private tramite admin.php. Ciò significa che non hai accesso all'intero ambiente WordPress, come ad esempio do_shortcode(), che si trova in /wp-includes/shortcodes.php.

Esiste comunque una soluzione alternativa (e lo stesso vale per oEmbed). Ecco un esempio che puoi utilizzare nel tuo callback AJAX per abilitare sia i gestori oEmbed che i gestori di shortcode per la proprietà \WP_Post::post_content.

/** \WP_Post $post */
$post = get_post();

/** @var \WP_Embed $wp_embed */
global $wp_embed;

$wp_embed->post_ID = $post->ID;

// shortcode [embed]
$wp_embed->run_shortcode( $post->post_content );

// link semplici su una riga autonoma
$wp_embed->autoembed( $post->post_content );

// Abilita gli shortcode
do_shortcode( $post->post_content );

PROTip: Non chiamare mai direttamente echo do_shortcode( '[some-short-code arg="foo"]' );. Uno shortcode è semplicemente un segnaposto per l'editor. Ogni shortcode deve avere un callback associato. Utilizza invece il callback. Questo ti evita di eseguire controlli Regex dispendiosi.

25 mag 2012 21:28:18
Commenti

@djb Per favore aggiungi la tua soluzione non alla domanda, ma come una nuova risposta e poi contrassegnala come soluzione. Grazie.

kaiser kaiser
27 mag 2012 18:35:24

lo farò. puoi far luce sul mistero della function_exists?

djb djb
28 mag 2012 12:50:30
0

La soluzione è aggirare le restrizioni di admin-ajax gestendolo autonomamente, come suggerito da @OneTrickPony.

add_action( 'init', function() { 
  ps_register_shortcode_ajax( 'ps_get_survey_form', 'ps_get_survey_form' ); 
} );

function ps_register_shortcode_ajax( $callable, $action ) {

  if ( empty( $_POST['action'] ) || $_POST['action'] != $action )
    return;

  call_user_func( $callable );
}

function ps_get_survey_form() {
    echo do_shortcode( '[contact-form-7 id="397" title="contact form 1"]' );
    die(); 
} 
28 mag 2012 12:51:37