tl;dr: Contact Form 7’s shortcode doesn’t work in an AJAX request when called with 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'}
}
});
});
However,
echo do_shortcode( '[contact-form-7 id="397" title="Contact form 1"]' )
returns the shortcode string itself. It works fine if I put it in a template.
Try as I might (ludicrous things like wrapping it in a post/applying the_content filter, manually firing various actions that CF7 hooks into, etc) it refuses to translate itself into a form.
How do I debug this?
EDIT
@Kaiser sensibly suggests that I don’t have access to do_shortcode. I tried to check this, with the following result:
function ps_get_survey_form() {
//include( ABSPATH . 'wp-includes/shortcodes.php' );
//Causes fatal error: cannot redeclare add_shortcode
if ( function_exists( 'do_shortcode ' ) ) {
echo "do_shortcode exists";
} else {
echo "do_shortcode doesn't exist"; // this gets echoed
}
do_shortcode( 'foo' ); // this fails silently, even though the function apparently hasn't been defined
//foo(); // Causes fatal error as expected
//echo do_shortcode( '[contact-form-7 id="397" title="contact form 1"]' );
die();
}
WP Ajax runs both public as well as closed calls via
admin.php
. This means that you don’t have access to the whole wp environment, such asdo_shortcode()
, which is inside/wp-includes/shortcodes.php
.This still can get worked around (and as well for oEmbed). See the following example that you could use in your AJAX callback to enable both oEmbed handlers as well as shortcode handlers for a
WP_Post::post_content
property.PROTip: Never call
echo do_shortcode( '[some-short-code arg="foo"]' );
directly. A shortcode is just a placeholder for the editor. Every shortcode must have a callback attached. Use the callback instead. This saves you from running expensive Regex checks.The answer is to sidestep admin-ajax restrictions by handling it yourself, as @OneTrickPony suggests.