Вопрос или проблема
Я использую AJAX для загрузки следующего набора постов на главной странице. Посты загружаются нормально, но шорткоды не отображаются. Я пытаюсь использовать функцию do_shortcode на контенте, который получает AJAX-запрос (хотя эксперты предложили не использовать do_shortcode), но, похоже, это не срабатывает.
Вот моя функция, которая обрабатывает запрос:
function theme_load_more_posts() {
check_ajax_referer( 'theme-load-more-posts-nonce', 'nonce' );
$args = isset( $_POST['query'] ) ? array_map( 'esc_attr', $_POST['query'] ) : array();
$args['post_type'] = isset( $args['post_type'] ) ? esc_attr( $args['post_type'] ) : 'post';
$args['paged'] = esc_attr( $_POST['page'] );
$args['post_status'] = 'publish';
ob_start();
$loop = new WP_Query( $args );
if( $loop->have_posts() ): while( $loop->have_posts() ): $loop->the_post();
get_content_template();
endwhile;
endif;
$data = ob_get_clean();
wp_send_json_success( do_shortcode($data) ); // Выполняем do_shortcode здесь, но это не работает.
wp_reset_postdata();
wp_die();
}
add_action( 'wp_ajax_theme_load_more_posts', 'theme_load_more_posts' );
add_action( 'wp_ajax_nopriv_theme_load_more_posts', 'theme_load_more_posts' );
Функция get_content_template()
загружает файл шаблона, который содержит обычный код WordPress для отображения содержимого постов.
Я пытался использовать do_shortcode_in_html()
на get_content_template()
, но это тоже не сработало.
Я также видел похожие темы по этому поводу, но они в основном касались проблем с самим AJAX-запросом. Я считаю, что моя проблема заключается в этой функции. Есть идеи?
Я считаю, что проблема в том, что вы не вызываете do_shortcode()
в буфере вывода. Вам не нужно выполнять цикл в буфере вывода, так как я предполагаю, что get_content_template()
просто возвращает HTML с встраиваемыми шорткодами. Сохраните это в строковую переменную, затем обработайте ее с помощью do_shortcode()
и сохраните вывод echo
в буфер.
Это непроверено, но должно направить вас в правильном направлении:
function theme_load_more_posts() {
check_ajax_referer( 'theme-load-more-posts-nonce', 'nonce' );
$args = isset( $_POST['query'] ) ? array_map( 'esc_attr', $_POST['query'] ) : array();
$args['post_type'] = isset( $args['post_type'] ) ? esc_attr( $args['post_type'] ) : 'post';
$args['paged'] = esc_attr( $_POST['page'] );
$args['post_status'] = 'publish';
$loopContent="";
$loop = new WP_Query( $args );
if( $loop->have_posts() ):
while( $loop->have_posts() ): $loop->the_post();
$loopContent .= get_content_template();
endwhile;
endif;
ob_start();
echo do_shortcode($loopContent);
$data = ob_get_clean();
wp_send_json_success( $data ); // Выполняем do_shortcode здесь, но это не работает.
wp_reset_postdata();
wp_die();
}
add_action( 'wp_ajax_theme_load_more_posts', 'theme_load_more_posts' );
add_action( 'wp_ajax_nopriv_theme_load_more_posts', 'theme_load_more_posts' );
Ответ или решение
Проблема с недействующими шорткодами в AJAX-вызове: решение
При попытке загрузки следующего набора постов на главной странице с помощью AJAX возникает проблема: шорткоды, содержащиеся в HTML-коде, не обрабатываются должным образом. В этой статье мы разберёмся, как правильно использовать функцию do_shortcode()
для обработки шорткодов в контексте AJAX-вызовов в WordPress, а также предложим оптимальное решение, основанное на вашем коде.
Описание проблемы
Ваш текущий код использует функцию do_shortcode()
после формирования HTML-кода из постов. Однако шорткоды не обрабатываются, что может быть связано с тем, что вы пытаетесь выполнять do_shortcode()
на некорректном уровне абстракции, когда контент уже находится в буфере вывода.
Решение
Чтобы корректно обработать шорткоды, необходимо собрать весь контент в отдельную переменную, а затем применить к ней do_shortcode()
. Это позволит вам гарантировать, что все шорткоды будут распознаны и обработаны.
Вместо того чтобы вызывать do_shortcode()
на буфере вывода, давайте изменим его использование следующим образом:
function theme_load_more_posts() {
check_ajax_referer( 'theme-load-more-posts-nonce', 'nonce' );
$args = isset( $_POST['query'] ) ? array_map( 'esc_attr', $_POST['query'] ) : array();
$args['post_type'] = isset( $args['post_type'] ) ? esc_attr( $args['post_type'] ) : 'post';
$args['paged'] = esc_attr( $_POST['page'] );
$args['post_status'] = 'publish';
// Создаем переменную для хранения контента
$loopContent = "";
$loop = new WP_Query( $args );
if( $loop->have_posts() ):
while( $loop->have_posts() ): $loop->the_post();
// Сохраняем контент каждого поста в переменную
$loopContent .= get_content_template();
endwhile;
endif;
// Применяем do_shortcode к скомпонованному контенту
$data = do_shortcode( $loopContent );
// Отправляем обратно JSON с обработанным контентом
wp_send_json_success( $data );
wp_reset_postdata();
wp_die();
}
add_action( 'wp_ajax_theme_load_more_posts', 'theme_load_more_posts' );
add_action( 'wp_ajax_nopriv_theme_load_more_posts', 'theme_load_more_posts' );
Объяснение кода
-
Сбор контента: Мы создаём переменную
$loopContent
, которая будет использоваться для аккамуляции HTML-кода каждого загружаемого поста. Это делается через конкатенацию контента, который возвращает функцияget_content_template()
. -
Обработка шорткодов: После того как весь контент будет собран, мы применяем к нему
do_shortcode()
. Это обеспечит обработку всех шорткодов перед отправкой результата обратно на клиент. -
Отправка данных: Наконец, функция
wp_send_json_success()
используется для отправки успешно обработанного контента на фронтенд.
Заключение
Данная модификация вашего кода должна помочь в корректной обработке шорткодов при загрузке постов через AJAX. Убедитесь, что все шорткоды, которые вы планируете использовать, поддерживаются и правильно зарегистрированы. При дальнейших вопросах или необходимости оптимизации, не стесняйтесь обращаться за помощью.