Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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();
}
share|improve this question
1  
Maybe because the shortcode function hasn't been registered yet at that point? –  onetrickpony May 25 '12 at 17:10
    
@OneTrickPony - I agree that seems likely. The question is, how can I cause it to be registered (if you see what I mean)? –  djb May 26 '12 at 10:56
1  
Just handle the ajax request yourself in the "wp" or "init" action. WP's admin-ajax was designed to be used in the administration area anyway –  onetrickpony May 26 '12 at 12:05
    
@OneTrickPony, thanks. that works. will post working code above for posterity. –  djb May 26 '12 at 13:54
    
Last time I looked through Contact Form 7, they didn't use the build in shortcode API, opting to role their own instead. Worth checking out. –  chrisguitarguy Jul 31 '12 at 18:47
add comment

2 Answers

up vote 2 down vote accepted

The answer is to sidestep admin-ajax restrictions by handling it yourself, as @OneTrickPony suggests.

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(); 
} 
share|improve this answer
add comment

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 as do_shortcode(), which is inside /wp-includes/shortcodes.php.

share|improve this answer
    
thanks! but see edits, above –  djb May 26 '12 at 11:13
    
@djb Please add your solution not to the question, but as a new answer and mark it then as solution. Thanks. –  kaiser May 27 '12 at 15:35
    
will do. can you shed any light on the function_exists mystery? –  djb May 28 '12 at 9:50
    
@djb I could. But I'd need to have a full working ajax example (pastebin?), so I can dig into it. Else I don't have enough time. :) –  kaiser May 29 '12 at 0:38
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.