WordPress的filter来修改最终的HTML输出

WordPress的很好的filter支持获取各种特定位的内容,并修改它之前输出。 就像“the_content”filter一样,它允许您在输出到屏幕之前访问post的标记。

我试图find一个全面的filter,给我最后一个修改最后的标记完整的输出之前的裂缝。 任何人都知道吗?

我多次浏览filter列表,但没有发现任何内容: http : //adambrown.info/p/wp_hooks/hook/filters

(我已经为这个问题挖掘了一些WordPress的特定社区,但没有收到一个单一的答复,以为我会转向老生常谈。)

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> */ 

WordPress没有“最终输出”filter,但你可以在一起。 下面的示例驻留在我为项目创build的“必须使用”插件中。

注意:我还没有testing任何可能使用“关机”操作的插件。

该插件通过遍历所有打开的缓冲区级别来工作,closures它们并捕获它们的输出。 然后触发“final_output”filter,回应过滤的内容。

不幸的是,WordPress执行几乎完全相同的过程(closures打开的缓冲区),但实际上并没有捕获缓冲区进行过滤(只是刷新它),所以额外的“closures”操作将无法访问它。 正因为如此,下面的动作优先于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_outputfilter的示例:

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

这个问题也许是旧的,但我find了一个更好的方法来做到这一点。

 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_startbuffer_end

在html的标题部分的末尾执行buffer_start 。 参数( callback函数)在输出缓冲结束时被调用。 这发生在页脚的第二个注册动作buffer_end执行时。

callback函数是您添加代码以更改输出值( $buffervariables)的位置。 然后,您只需返回修改后的代码,即可显示页面。

注意请确保为buffer_startbuffer_endcallback使用唯一的函数名称,以免它们与插件中的其他函数发生冲突。

@jacer,如果你使用下面的钩子,header.php也包含在内。

 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插件。 这将最终的网页写入文件进行caching。 看看插件如何工作可能会给你一些想法。

事实上,最近有关WP-Hackers邮件列表的关于整页修改主题的讨论,似乎共识是输出缓冲与ob_start()等是唯一真正的解决scheme。 还有一些关于它的优点和缺点的讨论: http : //groups.google.com/group/wp-hackers/browse_thread/thread/e1a6f4b29169209a#

总结一下:它的工作原理是必要时的最佳解决scheme(如WP-Supercache插件),但会降低整体速度,因为您的内容不允许发送到浏览器,而必须等待完整的文档将被呈现(对于ob_end()),然后才能被您处理并发送到浏览器。

我遇到了这个代码的问题,因为我最终看起来似乎是页面的原始来源,所以一些插件对页面没有任何影响。 我现在正试图解决这个问题 – 我发现了许多关于从wordpress收集输出的最佳实践的信息。

更新和溶剂:

来自KFRIEND的代码没有为我工作,因为这捕获来自WordPress的未经处理的来源,而不是在浏览器事实结果相同的输出。 使用全局variables来缓冲内容,我的溶剂可能不是很好 – 但至less我知道得到的是与传递给浏览器相同的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');