Wordpress过滤器修改最终的html输出

chi*_*ior 54 wordpress

Wordpress具有很好的过滤器支持,可以获取各种特定内容并在输出之前对其进行修改.就像"the_content"过滤器一样,它允许您在帖子输出到屏幕之前访问帖子的标记.

我正在尝试找到一个全能过滤器,它在输出之前完全修改最终标记给我一个最后的破解.谁知道一个?

我已多次浏览过滤器列表,但没有任何内容突然出现在我身上:http: //adambrown.info/p/wp_hooks/hook/filters

(我已经针对这个问题点了一些特定于Wordpress的社区,但没有收到一个回复​​,我以为我会转向那个值得尊敬的SO.)

kfr*_*end 55

WordPress没有"最终输出"过滤器,但你可以一起破解.下面的示例位于我为项目创建的"必须使用"插件中.

注意:我没有使用任何可能使用"关闭"操作的插件进行测试.

该插件通过迭代所有打开的缓冲区级别,关闭它们并捕获它们的输出来工作.然后它会触发"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);
Run Code Online (Sandbox Code Playgroud)

挂钩到final_output过滤器的示例:

<?php

add_filter('final_output', function($output) {
    return str_replace('foo', 'bar', $output);
});
Run Code Online (Sandbox Code Playgroud)

编辑:

此代码使用匿名函数,这些函数仅在PHP 5.3或更高版本中受支持.如果您使用的是PHP 5.2或更高版本的网站,那么您自己也会受到伤害.PHP 5.2于2006年发布,即使Wordpress STILL支持它,也不应该使用它.

  • 自发布以来,我已经在更多的项目中使用了这个,并且从3.8开始使用WP的所有版本.我没有遇到任何问题. (3认同)
  • 非常感谢,这是最优雅的解决方案。 (2认同)
  • @Robert,如果你这样做,那么 WP 的默认操作将运行关闭操作,这将刷新所有的 ob 级别。默认操作不捕获输出,只是刷新它,因此“final_output”过滤器不会捕获任何内容。至少我相信。 (2认同)
  • 为什么`count(ob_get_level())`?实际上ob_get_level()返回级别(int).尝试`while(ob_get_level())$ final.= ob_get_clean();` (2认同)
  • 像魅力一样工作-4.9.8 (2认同)

mof*_*off 20

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>
*/
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用php register_shutdown_function来结束缓冲,并检索html. (3认同)

Jac*_*mri 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');
Run Code Online (Sandbox Code Playgroud)

说明 此插件代码注册两个操作 - buffer_startbuffer_end.

buffer_start在html的标题部分的末尾执行.callback在输出缓冲结束时调用参数function.当第二个注册的动作buffer_end执行时,这发生在页面的页脚.

callback函数用于添加代码以更改输出值($buffer变量).然后,您只需返回修改后的代码,即可显示页面.

注意 一定要使用独特的功能,名字buffer_start,buffer_endcallback,这样他们就不会与您可能在插件等功能相冲突.


小智 13

@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');
Run Code Online (Sandbox Code Playgroud)

  • [http://www.dagondesign.com/articles/wordpress-hook-for-entire-page-using-output-buffering/](http://www.dagondesign.com/articles/wordpress-hook-for-entire -page-using-output-buffering /) - 这是从这个答案中复制出来的链接. (2认同)

Arn*_*e L 7

我使用了这篇文章的顶级解决方案(由 kfriend)有一段时间了。它使用 anmu-plugin来缓冲整个输出。

但是这个解决方案破坏了缓存,wp-super-cache并且当我上传mu-plugin.

所以:如果你正在使用wp-super-cache,你可以像这样使用这个插件的过滤器:

add_filter('wp_cache_ob_callback_filter', function($buffer) {
    $buffer = str_replace('foo', 'bar', $buffer);
    return $buffer;
});
Run Code Online (Sandbox Code Playgroud)


Ada*_*aft 6

为了简化以前的答案,只需在中使用它functions.php

ob_start();
add_action('shutdown', function () {
    $html = ob_get_clean();
    // ... modify $html here
    echo $html;
}, 0);
Run Code Online (Sandbox Code Playgroud)


okt*_*kto 5

修改了/sf/users/29377141/答案。

所有代码都在functions.php 上。您可以对“final_output”过滤器上的 html 做任何您想做的事情。

在您主题的“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); 
});
Run Code Online (Sandbox Code Playgroud)