WordPress: Сайт перестаёт грузиться при навигации после перемещения блока через output buffering

Рейтинг: 1Ответов: 0Опубликовано: 14.08.2025

Использую output buffering в WordPress для перемещения блока term-description (SEO-оптимизация). Код корректно работает при первой загрузке страницы, но при переходе на другие страницы сайт перестаёт грузиться (белый экран или бесконечная загрузка).

Что делает код:

  • Находит блок <div class="term-description">
  • Создает плейсхолдер с теми же стилями
  • Переносит оригинальный блок после <body> (скрыто, для SEO)
  • Добавляет JS для синхронизации содержимого

Попробовал:

  • Очистку кеша
  • Отключение других плагинов
  • Упрощение JS-часта

Вопрос: Почему буферизация ломает загрузку при навигации? Как это исправить?

add_action('template_redirect', function () {
    if (is_admin() || wp_doing_ajax() || is_feed()) return;

    ob_start(function ($html) {
        if (preg_match('#(<div[^>]*class=["\'][^"\']*term-description[^"\']*["\'][^>]*>.*?</div>)#is', $html, $m)) {
            $block = $m[1];

            // Создаем DOM для копирования стилей
            $dom = new DOMDocument();
            @$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
            $xpath = new DOMXPath($dom);
            
            // Находим оригинальный элемент
            $original = $xpath->query("//div[contains(@class, 'term-description')]")->item(0);
            
            if ($original) {
                // Копируем все стили из оригинала
                $styles = '';
                if ($original->hasAttribute('style')) {
                    $styles = $original->getAttribute('style');
                }
                
                // Копируем классы
                $classes = '';
                if ($original->hasAttribute('class')) {
                    $classes = $original->getAttribute('class');
                }
                
                // Создаем плейсхолдер с теми же размерами и стилями
                $placeholder = '<div id="term-description-placeholder" class="'.$classes.'" style="'.$styles.';visibility:hidden;height:auto!important;"></div>';
                
                // Вставляем плейсхолдер
                $html = str_replace($block, $placeholder, $html);
                
                // Вставляем оригинальный блок после body (для SEO)
                $html = preg_replace(
                    '#(<body[^>]*>)#i',
                    '$1' . "\n" . '<div class="seo-term-description" style="display:none!important;">' . $block . '</div>',
                    $html,
                    1
                );

                // Добавляем скрипт для синхронизации
                $script = <<<JS
<script>
(function(){
    function syncElements() {
        var original = document.querySelector('.seo-term-description > div');
        var placeholder = document.getElementById('term-description-placeholder');
        
        if (!original || !placeholder) return;
        
        // Копируем содержимое
        placeholder.innerHTML = original.innerHTML;
        
        // Показываем плейсхолдер
        placeholder.style.visibility = 'visible';
        
        // Обновляем размеры при изменениях
        var observer = new MutationObserver(function() {
            placeholder.innerHTML = original.innerHTML;
        });
        
        observer.observe(original, {
            childList: true,
            subtree: true,
            characterData: true
        });
    }
    
    function init() {
        syncElements();
        window.addEventListener('resize', syncElements);
        window.addEventListener('scroll', syncElements, {passive: true});
        
        // Для динамических изменений в блоках
        setInterval(syncElements, 1000);
    }
    
    if (document.readyState === 'complete') {
        init();
    } else {
        document.addEventListener('DOMContentLoaded', init);
    }
})();
</script>
JS;
                $html = str_replace('</body>', $script . '</body>', $html);
            }
        }
        return $html;
    });
});

Ответы

Ответов пока нет.