Почему "сделать шорткод" плагина может не работать в запросе AJAX?
Tl;dr: Шорткод контактной формы 7 не работает в запросе AJAX при вызове с 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'}
}
});
});
Однако,
echo do_shortcode( '[contact-form-7 id="397" title="Contact form 1"]' )
Возвращает саму строку шорткода. Это прекрасно работает, если я помещу его в шаблон.
Как бы я ни старался (нелепые вещи, такие как упаковка в сообщение/применение фильтра_контента, запуск вручную различных действий, к которым подключается 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();
}
2 answers
WP Ajax выполняет как публичные, так и закрытые вызовы через admin.php
. Это означает, что у вас нет доступа ко всей среде wp, такой как do_shortcode()
, которая находится внутри /wp-includes/shortcodes.php
.
Это все еще можно обойти (а также для 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 );
Подсказка: Никогда не звоните echo do_shortcode( '[some-short-code arg="foo"]' );
напрямую. Короткий код - это просто заполнитель для редактора. Каждый короткий код должен иметь прикрепленный обратный вызов. Вместо этого используйте обратный вызов. Это избавляет вас от выполнения дорогостоящих проверок регулярных выражений.
Ответ заключается в том, чтобы обойти ограничения admin-ajax, обработав его самостоятельно, как предлагает @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();
}