Фильтр Wordpress для изменения окончательного вывода html

wordpress

31471 просмотра

10 ответа

Wordpress имеет отличную поддержку фильтра для получения всех видов определенных бит контента и изменения его перед выходом. Как фильтр «the_content», который позволяет вам получить доступ к разметке для сообщения, прежде чем он выйдет на экран.

Я пытаюсь найти фильтр catch-all, который дает мне последнюю трещину при модификации окончательной разметки целиком до вывода. Кто-нибудь знает об одном?

Я просматривал список фильтров несколько раз, но на меня ничего не выпрыгивает: http://adambrown.info/p/wp_hooks/hook/filters

(Я затронул некоторые сообщества Wordpress для этого вопроса, но, не получив ни одного ответа, подумал, что я обращусь к почтенному SO.)

Автор: chipotle_warrior Источник Размещён: 17.05.2019 03:55

Ответы (10)


15 плюса

Решение

AFAIK, для этого нет никакого крючка, поскольку темы используют HTML, который не будет обрабатываться WordPress.

Однако вы можете использовать выходную буферизацию, чтобы поймать окончательный HTML:

<?php
// example from php.net
function callback($buffer) {
  // replace all the apples with oranges
  return (str_replace("apples", "oranges", $buffer));
}
ob_start("callback");
?>
<html><body>
<p>It's like comparing apples to oranges.</p>
</body></html>
<?php ob_end_flush(); ?>
/* output:
   <html><body>
   <p>It's like comparing oranges to oranges.</p>
   </body></html>
*/
Автор: moff Размещён: 21.04.2009 01:20

45 плюса

WordPress не имеет фильтра «окончательного вывода», но вы можете взломать его. Нижеприведенный пример находится в плагине «Обязательно использовать», который я создал для проекта.

Примечание. Я не тестировал никаких плагинов, которые могли бы использовать действие «shutdown».

Плагин работает, повторяя все уровни открытого буфера, закрывая их и фиксируя их вывод. Затем он отключается от фильтра «final_output», повторяя отфильтрованный контент.

К сожалению, WordPress выполняет почти тот же самый процесс (закрытие открытых буферов), но фактически не захватывает буфер для фильтрации (просто сбрасывает его), поэтому дополнительные действия «выключения» не будут иметь к нему доступа. Из-за этого ниже действие приоритизировано выше WordPress.

WP-содержание / мю-плагинов / buffer.php

<?php

/**
 * Output Buffering
 *
 * Buffers the entire WP process, capturing the final output for manipulation.
 */

ob_start();

add_action('shutdown', function() {
    $final = '';

    // We'll need to get the number of ob levels we're in, so that we can iterate over each, collecting
    // that buffer's output into the final output.
    $levels = ob_get_level();

    for ($i = 0; $i < $levels; $i++) {
        $final .= ob_get_clean();
    }

    // Apply any filters to the final output
    echo apply_filters('final_output', $final);
}, 0);

Пример подключения к фильтру final_output:

<?php

add_filter('final_output', function($output) {
    return str_replace('foo', 'bar', $output);
});

Редактировать:

Этот код использует анонимные функции, которые поддерживаются только в PHP 5.3 или новее. Если вы используете веб-сайт с использованием PHP 5.2 или старше, вы оказываете себе плохую услугу. PHP 5.2 был выпущен в 2006 году, и хотя Wordpress STILL поддерживает его, вы не должны его использовать.

Автор: kfriend Размещён: 02.04.2014 04:54

18 плюса

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

function callback($buffer) {
  // modify buffer here, and then return the updated code
  return $buffer;
}

function buffer_start() { ob_start("callback"); }

function buffer_end() { ob_end_flush(); }

add_action('wp_head', 'buffer_start');
add_action('wp_footer', 'buffer_end');

Объяснение Этот код плагина регистрирует два действия - buffer_startи buffer_end.

buffer_startвыполняется в конце секции заголовка html. Параметр, callbackфункция, вызывается в конце буферизации вывода. Это происходит на нижнем колонтитуле страницы, когда выполняется второе зарегистрированное действие buffer_end.

callbackФункция , где вы добавить свой код , чтобы изменить значение вывода ( $bufferпеременный). Затем вы просто возвращаете измененный код, и страница будет отображаться.

Примечания Обязательно используйте уникальные имена функций для buffer_start,, buffer_endи callback, таким образом, они не конфликтуют с другими функциями, которые могут быть у вас в плагинах.

Автор: Jacer Omri Размещён: 04.07.2013 02:25

10 плюса

@jacer, если вы используете следующие крючки, заголовок также включается.

function callback($buffer) {      
    $buffer = str_replace('replacing','width',$buffer);
    return $buffer; 
}

function buffer_start() { ob_start("callback"); } 
function buffer_end() { ob_end_flush(); }

add_action('after_setup_theme', 'buffer_start');
add_action('shutdown', 'buffer_end');
Автор: Nick Kuijpers Размещён: 25.10.2014 11:10

3 плюса

Вы можете попробовать посмотреть в файле wp-includes / formatting.php. Например, функция wpautop. Если вы ищете что-то со всей страницей, посмотрите на плагин Super Cache. Это записывает окончательную веб-страницу в файл для кэширования. Увидев, как эти плагины могут дать вам некоторые идеи.

Автор: Brent Baisley Размещён: 21.04.2009 01:23

3 плюса

Действительно, недавно была опубликована дискуссия о списке рассылки WP-Hackers по теме полной модификации страницы, и, похоже, консенсусом было то, что буферизация вывода с помощью ob_start () и т. Д. Была единственным реальным решением. Также были обсуждены проблемы и недостатки: http://groups.google.com/group/wp-hackers/browse_thread/thread/e1a6f4b29169209a#

Подводя итог: он работает и является лучшим решением при необходимости (например, в плагине WP-Supercache), но замедляет общие скорости, потому что ваш контент не может быть отправлен в браузер как готовый, но вместо этого приходится ждать полный документ для визуализации (для ob_end ()), прежде чем он может быть обработан вами и отправлен в браузер.

Автор: Размещён: 29.04.2009 09:31

2 плюса

Я использовал верхнее решение этого сообщения (от kfriend) некоторое время. Он использует mu-pluginдля буферизации весь вывод.

Но это решение нарушает кэширование, wp-super-cacheи никакие файлы supercache не генерируются при загрузке mu-plugin.

Итак: если вы используете wp-super-cache, вы можете использовать фильтр этого плагина следующим образом:

add_filter('wp_cache_ob_callback_filter', function($buffer) {
    $buffer = str_replace('foo', 'bar', $buffer);
    return $buffer;
});
Автор: Arne L Размещён: 04.07.2018 10:51

1 плюс

У меня возникли проблемы с этим кодом, так как в итоге я получаю исходный исходный код страницы, чтобы некоторые плагины не влияли на страницу. Я пытаюсь решить это сейчас - я havnt нашел много информации о лучших методах сбора данных из wordpress.

Обновление и разрешение:

Код от KFRIEND не работал для меня, так как он захватывает необработанный источник из wordpress, а не тот же вывод, который заканчивается в браузере infact. Мое решение, вероятно, не изящно, используя переменную globals для буферизации содержимого, но, по крайней мере, я знаю, что получается тот же собранный HTML-код, который доставляется в браузер. Возможно, что разные настройки плагинов создают проблемы, но благодаря примеру кода Jacer Omri выше я закончил с этим.

Этот код в моем случае находится, как правило, в functions.php в папке темы.

$GLOBALS['oldschool_buffer_variable'] = '';
function sc_callback($data){
    $GLOBALS['final_html'] .= $data;
    return $data;
}
function sc_buffer_start(){
    ob_start('sc_callback');
}
function sc_buffer_end(){
    // Nothing makes a difference in my setup here, ob_get_flush() ob_end_clean() or whatever
    // function I try - nothing happends they all result in empty string. Strange since the
    // different functions supposedly have very different behaviours. Im guessing there are 
    // buffering all over the place from different plugins and such - which makes it so 
    // unpredictable. But that's why we can do it oldschool :D
    ob_end_flush();

    // Your final HTML is here, Yeeha!
    $output = $GLOBALS['oldschool_buffer_variable'];
}
add_action('wp_loaded', 'sc_buffer_start');
add_action('shutdown', 'sc_buffer_end');
Автор: Kim Steinhaug Размещён: 12.10.2016 08:24

0 плюса

Изменен ответ https://stackoverflow.com/users/419673/kfriend .

Весь код будет на functions.php. Вы можете делать все, что хотите, с помощью html в фильтре «final_output».

На вашей функции 'functions.php'

//we use 'init' action to use ob_start()
add_action( 'init', 'process_post' );

function process_post() {
     ob_start();
}


add_action('shutdown', function() {
    $final = '';

    // We'll need to get the number of ob levels we're in, so that we can iterate over each, collecting
    // that buffer's output into the final output.
    $levels = ob_get_level();

    for ($i = 0; $i < $levels; $i++) {
        $final .= ob_get_clean();
    }

    // Apply any filters to the final output
    echo apply_filters('final_output', $final);
}, 0);

add_filter('final_output', function($output) {
    //this is where changes should be made
    return str_replace('foo', 'bar', $output); 
});
Автор: okto Размещён: 18.09.2018 02:20

0 плюса

Попробуйте сначала решить эту проблему с помощью JavaScript перед использованием выходных буферов.

Предположим, вы хотите добавить счетчик при загрузке iframe, например:

(function ($) {

    $(document).ready(function () {
        showSpinnerWhileIFrameLoads();
    });

    function showSpinnerWhileIFrameLoads() {
        var iframe = $('iframe');
        if (iframe.length) {
            $(iframe).before('<div id=\'spinner\'><i class=\'fa fa-spinner fa-spin fa-3x fa-fw\'></i></div>');
            $(iframe).on('load', function() {
                document.getElementById('spinner').style.display='none';
            });
        }
    }

})(jQuery);

Адаптируйте эту идею к вашим потребностям, как правило, вы должны иметь возможность манипулировать выходом HTML с помощью JavaScript без необходимости связываться с выходными буферами, которые могут, например, разбить кеш.

Автор: Lucas Bustamante Размещён: 04.11.2018 08:26
Вопросы из категории :
32x32