Вопрос или проблема
Я написал динамическую панель для своей темы WordPress, которую вызываю с помощью шорткода в редакторе WordPress и помещаю в нее свой контент.
Мой контент отображается правильно, но порядок его отображения полностью нарушен!?
Я попробовал многие методы и в конечном итоге смог как-то управлять выводом публикаций с помощью следующего кода:
// Функция отображения формата контента в выводе
function wrap_in_p_if_needed($content) {
$content = preg_replace('/<img\s+[^>]*src="([^"]+)"\s+[^>]*>/is', '', $content); // Удалить теги img
$content = preg_replace('/\+)"]\[\/video\]/is', '', $content); // Удалить теги видео
$content = preg_replace('/\+)"]\[\/audio\]/is', '', $content); // Удалить теги аудио
// Разделяем контент на абзацы по знаку **
$paragraphs = explode('**', $content);
// Создаем новую строку для хранения вывода
$output="";
// Добавляем каждый абзац в строку вывода в теге <p>
foreach ($paragraphs as $paragraph) {
$output .= '<p>' . trim($paragraph) . '</p>';
}
return $output;
}
В приведенном выше коде я смог разделить абзацы, которые были склеены, используя знак **, но есть другая проблема, для которой у меня нет решения!
Если в контенте есть медиа (фото-видео-аудио) между абзацами, они переместятся в конец панели?
Другими словами, сначала отображаются параграфы, а затем медиа!?
Теперь я просто хочу изменить вышеуказанную функцию, чтобы больше не нужно было использовать знаки ** для разделения абзацев, и чтобы выводимый контент отображался правильно и без проблем.
Весь код, который я написал для динамической панели, выглядит следующим образом:
function dynamic_panel($title, $content) {
// Добавьте var_dump для просмотра контента перед wp_kses (по желанию) (для тестирования)
// var_dump($content);
// Санитизируйте заголовок, чтобы избежать XSS
$sanitized_title = wp_kses($title, ['<h1><h2><h3><h4><h5><h6><p><span><strong><em><br><i>']);
// Санитизируйте контент, чтобы избежать XSS
$sanitized_content = wp_kses($content, array(
'p' => array(),
'span' => array(),
'strong' => array(),
'i' => array(),
'br' => array(),
'em' => array(),
'h1' => array(),
'h2' => array(),
'h3' => array(),
'h4' => array(),
'h5' => array(),
'h6' => array(),
'video' => array(),
'audio' => array(),
'img' => array(),
));
echo '<div id="HNSC_panelMine_1" class="HNSC_all-panel_About">';
echo '<div class="HNSC_body-panel_About">';
echo '<ul id="HNSC_panelChild_1" class="HNSC_ul-main-panel_About">';
echo '<li class="HNSC_li-title-panel_About">';
echo '<p class="fas fa-circle-chevron-right HNSC_ico-rightFApanel_About">­</p>';
echo '<p class="fas fa-circle-chevron-down HNSC_ico-downFApanel_About">­</p>';
echo '<h3>' . $sanitized_title . '</h3>';
echo '<ul class="HNSC_boxContect-panel_About">';
echo '<li class="HNSC_contect-panel_About">';
echo '<hr class="HNSC_start-hr-conPan_About">';
// Используйте функцию wrap_in_p_if_needed для форматирования контента
$formatted_content = wrap_in_p_if_needed($sanitized_content);
// Отобразите контент с форматированием
echo $formatted_content;
// Обработка и отображение изображений (включая GIF)
if (preg_match_all('/<img\s+[^>]*src="([^"]+)"\s+[^>]*>/is', $content, $matches)) {
foreach ($matches[1] as $image_url) {
echo '<img src="' . $image_url . '" alt="" />';
}
}
// Обработка и отображение видео с использованием wp_video_shortcode или oEmbed
if (preg_match('/\+)"]\[\/video\]/is', $content, $matches)) {
$video_url = esc_url( $matches[3] );
// Сначала мы пытаемся отобразить локальное видео
$video_embed = wp_video_shortcode( ' . '" height="' . $matches[2] . '"]' );
// Если локальное видео не отображается, мы используем oEmbed
if ( empty( $video_embed ) ) {
$video_embed = wp_oembed_get( $video_url, array( 'width' => $matches[1], 'height' => $matches[2] ) );
}
if ($video_embed) {
echo $video_embed;
} else {
echo '<p>Ошибка при встраивании видео</p>';
}
}
// Обработка и отображение аудио с использованием wp_audio_shortcode
if (preg_match('/\+)"]\[\/audio\]/is', $content, $matches)) {
$audio_url = $matches[1];
$audio_embed = wp_audio_shortcode('');
echo $audio_embed;
}
echo '<hr class="HNSC_end-hr-conPan_About">';
echo '</li>';
echo '</ul>';
echo '</li>';
echo '</ul>';
echo '</div>';
echo '</div>';
}
// Функция отображения формата контента в выводе
function wrap_in_p_if_needed($content) {
$content = preg_replace('/<img\s+[^>]*src="([^"]+)"\s+[^>]*>/is', '', $content); // Удалить теги img
$content = preg_replace('/\+)"]\[\/video\]/is', '', $content); // Удалить теги видео
$content = preg_replace('/\+)"]\[\/audio\]/is', '', $content); // Удалить теги аудио
// Разделяем контент на абзацы по знаку **
$paragraphs = explode('**', $content);
// Создаем новую строку для хранения вывода
$output="";
// Добавляем каждый абзац в строку вывода в теге <p>
foreach ($paragraphs as $paragraph) {
$output .= '<p>' . trim($paragraph) . '</p>';
}
return $output;
}
function dynamic_panel_shortcode($atts, $content) {
$title = $atts['title'] ?? '';
if (!$content) {
$content = $atts['content'] ?? '';
}
return dynamic_panel($title, $content);
}
add_shortcode('panel', 'dynamic_panel_shortcode');
Ответ или решение
Ваша задача заключается в том, чтобы упростить код функции wrap_in_p_if_needed
, чтобы он правильно вставлял абзацы, не требуя использования символов "**" для разделения. Вам нужно также гарантировать, что медиа-контент (изображения, видео и аудио) корректно остается на своих местах и не сдвигается в конец.
Ниже приведен переработанный код функции wrap_in_p_if_needed
, который обрабатывает контент, добавляя теги <p>
для абзацев и сохраняя порядок медиа-контента:
function wrap_in_p_if_needed($content) {
// Открываем теги для контента
$content = wp_kses_post($content);
// Удаляем медиа-теги, чтобы потом их восстановить
$media_tags = [];
preg_match_all('/(<img\s+[^>]*>|<video[^>]*>.*?<\/video>|<audio[^>]*>.*?<\/audio>)/is', $content, $media_tags);
// Убираем медиа-теги из контента, чтобы не путались с текстом
$content = preg_replace('/<img\s+[^>]*>|<video[^>]*>.*?<\/video>|<audio[^>]*>.*?<\/audio>/is', '', $content);
// Разделяем контент на абзацы по двум переносам (двойному переводу строки)
$paragraphs = preg_split('/\n\s*\n/', trim($content));
// Создаем выходную строку
$output = '';
// Добавляем каждый абзац в вывод с <p> тегами
foreach ($paragraphs as $paragraph) {
if (!empty(trim($paragraph))) {
$output .= '<p>' . trim($paragraph) . '</p>';
}
}
// Вставляем медиа-контент обратно
if (!empty($media_tags[0])) {
$output .= implode('', $media_tags[0]);
}
return $output;
}
Дополнительно, вам нужно будет внести изменения в основной код вашей панели, чтобы он корректно обрабатывал выходной контент:
function dynamic_panel($title, $content) {
// Санитизация заголовка
$sanitized_title = wp_kses($title, array('h1' => [], 'h2' => [], 'h3' => [], 'h4' => [], 'h5' => [], 'h6' => [], 'p' => [], 'span' => [], 'strong' => [], 'em' => [], 'br' => [], 'i' => []));
// Санитаризация контента
$sanitized_content = wp_kses_post($content);
echo '<div id="HNSC_panelMine_1" class="HNSC_all-panel_About">';
echo '<div class="HNSC_body-panel_About">';
echo '<ul id="HNSC_panelChild_1" class="HNSC_ul-main-panel_About">';
echo '<li class="HNSC_li-title-panel_About">';
echo '<h3>' . $sanitized_title . '</h3>';
echo '<ul class="HNSC_boxContect-panel_About">';
echo '<li class="HNSC_contect-panel_About">';
// Форматируем вывод контента
$formatted_content = wrap_in_p_if_needed($sanitized_content);
echo $formatted_content;
echo '</li>';
echo '</ul>';
echo '</li>';
echo '</ul>';
echo '</div>';
echo '</div>';
}
function dynamic_panel_shortcode($atts, $content) {
$title = $atts['title'] ?? '';
return dynamic_panel($title, $content);
}
add_shortcode('panel', 'dynamic_panel_shortcode');
Важные изменения:
- Вместо использования символов "**" для разделения абзацев теперь используются двойные переводы строки.
- Медиа-контент помещается обратно в конечный вывод после формата, что позволяет ему оставаться на своих местах.
Этот подход должен решить проблему с порядком отображения контента и освободить вас от необходимости использовать специальные символы для формирования абзацев.