web-dev-qa-db-ja.com

なぜプラグインの 'do_shortcode'が使えないのでしょう。 AJAX 要求?

tl; dr: do_shortcodeを指定して呼び出した場合、Form 7のショートコードがAJAX要求で機能しない

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'}
        }
    });
});

しかしながら、

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

ショートコード文字列自体を返します。テンプレートに入れるとうまくいきます。

私が思うように試してみてください(投稿でラッピングしたり、the_contentフィルタを適用したり、CF7がフックするさまざまなアクションを手動で起動したりするなど、おかしなことをします)。

これをデバッグするにはどうすればよいですか。

_編集_

@ Kaiserは、私がdo_shortcodeにアクセスできないと賢明に示唆しています。これを確認しようとしたところ、次の結果が得られました。

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();
}
6
djb

その答えは、@ OneTrickPonyが示唆しているように、admin-ajaxの制限を自分で処理することで回避することです。

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(); 
} 
3
djb

WP Ajaxは、admin.phpを介したパブリックコールとクローズドコールの両方を実行します。これは/wp-includes/shortcodes.phpの中にあるdo_shortcode()のようなwp環境全体にアクセスできないことを意味します。

これはまだ回避することができます(そしてoEmbedでも同様です)。次の例を参照してください。AJAXコールバックで、oEmbedハンドラと\WP_Post::post_contentプロパティのショートコードハンドラの両方を有効にするために使用できます。

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

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

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

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

// plain links on their own line
$wp_embed->autoembed( $post->post_content );

// Enable shortcodes
do_shortcode( $post->post_content );

PROTip: echo do_shortcode( '[some-short-code arg="foo"]' );を直接呼び出さないでください。ショートコードは単なるエディタのプレースホルダです。 すべての shortcode mustにはコールバックが添付されています。代わりにコールバックを使ってください。これにより、高価な正規表現チェックを実行する必要がなくなります。

5
kaiser