Wordpress имеет отличную поддержку фильтра для получения всех видов определенных бит контента и изменения его перед выходом. Как фильтр "the_content", который позволяет вам получить доступ к разметке для сообщения перед его выходом на экран.
Я пытаюсь найти фильтр catch-all, который дает мне последнюю трещину при модификации окончательной разметки целиком до вывода. Кто-нибудь знает об одном?
Я просматривал список фильтров несколько раз, но ничего не выпрыгивает на меня: http://adambrown.info/p/wp_hooks/hook/filters
(Я применил некоторые сообщества Wordpress для этого вопроса, но, не получив ни одного ответа, подумал, что я обращусь к почтенному SO.)
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 like comparing apples to oranges.</p>
</body></html>
<?php ob_end_flush(); ?>
/* output:
<html><body>
<p>It like comparing oranges to oranges.</p>
</body></html>
*/
WordPress не имеет фильтра "окончательного вывода", но вы можете взломать его. Ниже приведен пример "Must Use" плагин, который я создал для проекта.
Примечание. Я не тестировал никаких плагинов, которые могли бы использовать действие "shutdown".
Плагин работает, повторяя все уровни открытых буферов, закрывая их и фиксируя их вывод. Затем он отключает фильтр "final_output", эхо отфильтрованное содержимое.
К сожалению, WordPress выполняет почти тот же самый процесс (закрытие открытых буферов), но фактически не захватывает буфер для фильтрации (просто сбрасывает его), поэтому дополнительные действия "shutdown" не будут иметь к нему доступа. Из-за этого ниже действие приоритизировано выше 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 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);
});
вопрос может быть старым, но я нашел лучший способ сделать это.
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
, поэтому они не конфликтуют с другими функциями, которые могут быть у вас в плагинах.
buffer_start_so_772510
префикс или суффикс своих примеров: buffer_start_so_772510
или so_772510_callback
(я предпочитаю использовать суффикс, так как его легче читать). Таким образом, когда код появляется где-то еще, мы знаем, откуда он взялся;)
@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');
Вы можете попробовать найти файл wp-includes/formatting.php. Например, функция wpautop. Если вы ищете что-то со всей страницей, посмотрите на плагин Super Cache. Это записывает окончательную веб-страницу в файл для кэширования. Увидев, как эти плагины могут дать вам некоторые идеи.
В последнее время в списке рассылки WP-Hackers появилась дискуссия о теме полной модификации страницы, и, похоже, консенсус заключался в том, что буферизация вывода с помощью ob_start() и т.д. была единственным реальным решением. Также обсуждались проблемы и недостатки: http://groups.google.com/group/wp-hackers/browse_thread/thread/e1a6f4b29169209a#
Подводя итог: он работает и является лучшим решением при необходимости (например, в плагине WP-Supercache), но замедляет общие скорости, потому что ваш контент не может быть отправлен в браузер как готовый, но вместо этого он должен дождаться полного документа, который будет отображаться (для ob_end()), прежде чем он может быть обработан вами и отправлен в браузер.
У меня возникли проблемы с этим кодом, так как я получаю исходный исходный код страницы, чтобы некоторые плагины не влияли на страницу. Я пытаюсь решить это сейчас - я 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 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');
ob_start, ob_clean, ..
внутри обратного вызова, что необходимо для определенной логики кэширования. php.net/manual/en/...