De ce funcția 'do_shortcode' a unui plugin poate să nu funcționeze într-o cerere AJAX?

25 mai 2012, 20:02:18
Vizualizări: 19K
Voturi: 9

tl;dr: Shortcode-ul Contact Form 7 nu funcționează într-o cerere AJAX când este apelat cu 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'}
        }
    });
});

Totuși,

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

returnează chiar string-ul shortcode-ului. Funcționează corect dacă îl pun într-un template.

Am încercat diverse metode (inclusiv lucruri absurde cum ar fi înfășurarea într-un post/aplicarea filtrului the_content, declanșarea manuală a diverselor acțiuni la care se conectează CF7), dar refuză să se transforme într-un formular.

Cum pot depana această problemă?

EDIT

@Kaiser sugerează în mod logic că nu am acces la do_shortcode. Am încercat să verific acest lucru, cu următorul rezultat:

function ps_get_survey_form() {

    //include( ABSPATH . 'wp-includes/shortcodes.php' ); 
    //Cauzează eroare fatală: nu se poate redeclara add_shortcode

    if ( function_exists( 'do_shortcode ' ) )  {
        echo "do_shortcode există";
    } else {
        echo "do_shortcode nu există";  // acest mesaj este afișat
    }

    do_shortcode( 'foo' );      // eșuează în tăcere, chiar dacă funcția aparent nu a fost definită
    //foo();                    // Cauzează eroare fatală așa cum era de așteptat

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

Poate pentru că funcția de shortcode încă nu a fost înregistrată în acel moment?

onetrickpony onetrickpony
25 mai 2012 20:10:15

@OneTrickPony - Sunt de acord că asta pare probabil. Întrebarea este, cum pot face să fie înregistrată (dacă înțelegi la ce mă refer)?

djb djb
26 mai 2012 13:56:05

Pur și simplu gestionează singur cererea ajax în acțiunea "wp" sau "init". Admin-ajax din WP a fost proiectat să fie folosit în zona de administrare oricum

onetrickpony onetrickpony
26 mai 2012 15:05:00

@OneTrickPony, mulțumesc. funcționează. voi posta codul funcțional mai sus pentru posteritate.

djb djb
26 mai 2012 16:54:57

Ultima dată când am verificat Contact Form 7, ei nu au folosit API-ul intern de shortcode, optând să își implementeze propria soluție. Merită verificat.

chrisguitarguy chrisguitarguy
31 iul. 2012 21:47:41

Nu știu ce se întâmplă în apelul ajax. Pentru că dacă încerc funtion_exists ca mai sus pentru get_option() astfel if(function_exists('get_option')){echo 'exist';}else{echo 'not exist';} afișează not exist dar când pur și simplu afișez de exemplu numele blogului get_option('blogname'); afișează numele blogului. Îl pot vedea în răspunsul ajax. Dacă funcția nu există, atunci cum poate funcționa? do_shortcode() de asemenea funcționează când încerc să obțin titlul site-ului. Dar când încerc să obțin titlul postării, nu se afișează. Care ar putea fi problema? @onetrickpony

sun sun
27 mai 2014 16:04:35

@sun Te rog să citești [ask] și să îți pui propria întrebare.

kaiser kaiser
27 mai 2014 16:07:44
Arată celelalte 2 comentarii
Toate răspunsurile la întrebare 2
2

WP Ajax rulează atât apeluri publice cât și cele închise prin intermediul admin.php. Aceasta înseamnă că nu ai acces la întregul mediu wp, cum ar fi do_shortcode(), care se află în /wp-includes/shortcodes.php.

Această limitare poate fi depășită (la fel ca și pentru oEmbed). Următorul exemplu poate fi folosit în callback-ul tău AJAX pentru a activa atât handler-ele oEmbed cât și cele pentru shortcode-uri pentru proprietatea \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-uri simple pe propria linie
$wp_embed->autoembed( $post->post_content );

// Activează shortcode-urile
do_shortcode( $post->post_content );

PROTip: Nu apela niciodată direct echo do_shortcode( '[some-short-code arg="foo"]' );. Un shortcode este doar un substitut pentru editor. Fiecare shortcode trebuie să aibă un callback asociat. Folosește callback-ul în schimb. Asta te scapă de verificări costisitoare cu Regex.

25 mai 2012 21:28:18
Comentarii

@djb Te rog să adaugi soluția ta nu la întrebare, ci ca un răspuns nou și apoi să îl marchezi ca soluție. Mulțumesc.

kaiser kaiser
27 mai 2012 18:35:24

o voi face. poți să arunci o lumină asupra misterului function_exists?

djb djb
28 mai 2012 12:50:30
0

Răspunsul este să ocolim restricțiile admin-ajax prin gestionarea manuală, așa cum sugerează @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="formular de contact 1"]' );
    die(); 
} 
28 mai 2012 12:51:37