Как оборачивать каждый элемент в div WP?
Есть такая функция с регуляркой, которая оборачивает все блоки на фронте в 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 человек (все зависит от конфигурации сервера) - Артем Колчин, регулярки применять можно, но не так как сейчас
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Оборачивать 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);
Если контент классический, можно использовать
DOMDocument, но он тоже требует аккуратности с кодировкой и фрагментами HTML.Простой CSS-вариант часто лучше: вместо физической обёртки задайте стили прямым детям контента:
.entry-content > * { margin-bottom: 24px; }
Если обёртка нужна для анимаций, якорей или аналитики, подумайте, нельзя ли добавить класс нужным блокам через
render_blockили настройки Gutenberg. Массовое вмешательство вthe_contentможет сломать галереи, таблицы, формы и embeds.Итог: не оборачивайте HTML регуляркой. Для Gutenberg используйте
parse_blocks(), для простых визуальных отступов используйте CSS, а DOMDocument оставьте только для случаев, где действительно нужно менять HTML-структуру.