Как оборачивать каждый элемент в div WP?

Ссылка скопирована
1 ответ

Есть такая функция с регуляркой, которая оборачивает все блоки на фронте в div

public static function wrap_content_in_div($content)     {         if (is_single() && is_singular('post')) {             // Определение регулярного выражения для обнаружения тегов, которые нужно обернуть              $pattern = '/<(b(?:h[1-6]|p|ul|ol)b)([^>]*)>([sS]*?)</1>/i';              // Замена совпадений с использованием preg_replace_callback             $content_with_wraps = preg_replace_callback($pattern, function ($matches) {                 $tag = $matches[1];                 $attributes = $matches[2];                 $inner_content = $matches[3];                  // Определение класса для обертки в зависимости от тега                 $wrapper_class = ($tag === 'p') ? 'wrap__padding' : (($tag === 'img') ? 'wrap__img' : 'wrap__full');                   // Формирование обертки и возвращение результата                 return "<div class='article__text $wrapper_class article__text_column article__holder'>$matches[0]</div>";             }, $content);              return $content_with_wraps;         } else {             return $content;         }     }  add_filter('the_content', [__CLASS__, 'wrap_content_in_div'], 100);

public static function wrap_content_in_div($content) { if (is_single() && is_singular('post')) { // Определение регулярного выражения для обнаружения тегов, которые нужно обернуть $pattern = '/<(b(?:h[1-6]|p|ul|ol)b)([^>]*)>([sS]*?)</1>/i'; // Замена совпадений с использованием preg_replace_callback $content_with_wraps = preg_replace_callback($pattern, function ($matches) { $tag = $matches[1]; $attributes = $matches[2]; $inner_content = $matches[3]; // Определение класса для обертки в зависимости от тега $wrapper_class = ($tag === 'p') ? 'wrap__padding' : (($tag === 'img') ? 'wrap__img' : 'wrap__full'); // Формирование обертки и возвращение результата return "<div class='article__text $wrapper_class article__text_column article__holder'>$matches[0]</div>"; }, $content); return $content_with_wraps; } else { return $content; } } add_filter('the_content', [__CLASS__, 'wrap_content_in_div'], 100);

Но проблема в том что есть шорткоды которые тоже используются со своей версткой и нужно чтоб обертка срабатывала только для корневых элементов.

Точнее не совсем понимаю приоритет обработки шорткодов и и моей функции.
Моей функции я задал приоритет 100, она всё оборачивает как нужно. Но вот если вмешивается шорткод, то обертка начинается и внутри, хотелось бы чтоб только корневые блоки оборачивал в div

Дополнительно:

Выкинь это вообще. Это только создаёт нагрузку.

Ответы:

Посмотрите в коде где у вас функция создания шорткода и ее приоритет, после этого просто укажите приоритет обертке раньше (ближе к 1). Скорее всего приоритет шорткода стоит 10.
PS На вашем месте я бы лучше шаблон переписал , делать регулярку чтоб он оборачивал все в div сомнительное занятие

  • А почему с регулярками не стоит связываться?
  • Артем Колчин, представь какую нагрузку ты даешь на сервер чтоб он на всех страницах удовлетворяющих условию if (is_single() && is_singular('post')) искал по твоей регулярке совпадение и дальше добавлял в html обертку . Во время разработки явно что-то пошло не так ))
    PS Возможно сейчас этот сайт посещают не много людей и ты не видишь тормозов, цп справляется, веселье начнется от 1000 человек (все зависит от конфигурации сервера)
  • Артем Колчин, регулярки применять можно, но не так как сейчас
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Никита Орлов Ответ

Оборачивать HTML регуляркой в WordPress — плохая идея, если речь не о совсем простом фрагменте. Регулярное выражение быстро ломается на вложенных тегах, атрибутах, комментариях, shortcodes, Gutenberg-блоках и некорректной разметке.

Если нужно обернуть каждый верхнеуровневый элемент контента в div, используйте DOM-парсер или, ещё лучше, работайте с блоками Gutenberg через parse_blocks().

Для блочной темы/контента Gutenberg логика такая:

add_filter('the_content', function ($content) {
    if (!is_singular('post') || is_admin()) {
        return $content;
    }
 
    $blocks = parse_blocks($content);
    $html = '';
 
    foreach ($blocks as $block) {
        $rendered = render_block($block);
 
        if (trim($rendered) === '') {
            continue;
        }
 
        $html .= '<div class="content-block">' . $rendered . '</div>';
    }
 
    return $html;
}, 20);

add_filter('the_content', function ($content) { if (!is_singular('post') || is_admin()) { return $content; } $blocks = parse_blocks($content); $html = ''; foreach ($blocks as $block) { $rendered = render_block($block); if (trim($rendered) === '') { continue; } $html .= '<div class="content-block">' . $rendered . '</div>'; } return $html; }, 20);

Если контент классический, можно использовать DOMDocument, но он тоже требует аккуратности с кодировкой и фрагментами HTML.

Простой CSS-вариант часто лучше: вместо физической обёртки задайте стили прямым детям контента:

.entry-content > * {
    margin-bottom: 24px;
}

.entry-content > * { margin-bottom: 24px; }

Если обёртка нужна для анимаций, якорей или аналитики, подумайте, нельзя ли добавить класс нужным блокам через render_block или настройки Gutenberg. Массовое вмешательство в the_content может сломать галереи, таблицы, формы и embeds.

Итог: не оборачивайте HTML регуляркой. Для Gutenberg используйте parse_blocks(), для простых визуальных отступов используйте CSS, а DOMDocument оставьте только для случаев, где действительно нужно менять HTML-структуру.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно