2009-04-21 3 views
40

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

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

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

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

ответ

14

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

Вы можете, однако, use output buffering поймать окончательный 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> 
*/ 
+1

Вы можете использовать php register_shutdown_function для завершения буферизации и извлечения html. – Simon

+0

У этого есть один недостаток, вы не можете вызвать 'ob_start, ob_clean, ..' внутри обратного вызова, который необходим для конкретной логики кэширования. http://php.net/manual/en/function.ob-start.php#refsect1-function.ob-start-parameters –

3

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

2

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

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

19

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

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, так что они не вступают в противоречие с другими функциями, вы можете иметь в плагинах.

+1

Вы можете префикс или суффикс ваших примеров: 'buffer_start_so_772510' или' so_772510_callback' (я предпочитаю суффикс , так как его легче читать). Таким образом, когда код находится где-то в другом месте, мы знаем, откуда оно взялось;) – brasofilo

+0

это не работает, когда вещи, которые вы хотите изменить или удалить, существуют после элемента нижнего колонтитула – user225269

+0

Я рекомендую использовать решение kwoodfriend, потому что это очень много безопаснее (например, вы можете быть уверены, что будете последним, чтобы манипулировать выходом). – Robert

38

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

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

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

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

в.ч.-контента/мю-плагинов/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 поддерживает его, вы не должны его использовать.

+1

Примечание: Я тестировал это только в версии 3.8. – kfriend

+1

Большое спасибо, это самое элегантное решение. – petermolnar

+0

Удивительный, безусловно, самый изящный! – Robert

7

@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'); 
+1

Старайтесь не делать сообщение, которое ссылается на другой ответ (и требует чтения другого ответа, чтобы получить контекст); чем более разделен ваш ответ от ответа, на который вы ссылаетесь, тем труднее понять, что вы говорите. Кроме того, не обязательно печатать ответ, который строится на других, если вы даете кредит, где должен быть кредит. –

+2

[http://www.dagondesign.com/articles/wordpress-hook-for-entire-page-using-output-buffering/](http://www.dagondesign.com/articles/wordpress-hook-for- all-page-using-output-buffering /) - это ссылка, с которой этот ответ был скопирован. –

1

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

Update и гуманного:

Код из 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'); 
Смежные вопросы