Wordpress filter to modify final html output

2019-01-10 09:59发布

Wordpress has great filter support for getting at all sorts of specific bits of content and modifying it before output. Like "the_content" filter, which lets you access the markup for a post before it's output to the screen.

I'm trying to find a catch-all filter that gives me one last crack at modifying the final markup in its entirety before output. Anyone know of one?

I've browsed the list of filters a number of times, but nothing jumps out at me: http://adambrown.info/p/wp_hooks/hook/filters

(I've tapped some Wordpress-specific communities for this question, but not having received a single reply, thought I'd turn to the venerable SO.)

标签: wordpress
10条回答
三岁会撩人
2楼-- · 2019-01-10 10:22

@jacer, if you use the following hooks, the header.php also gets included.

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');
查看更多
看我几分像从前
3楼-- · 2019-01-10 10:26

I was using the top solution of this post (by kfriend) for a while. It uses an mu-plugin to buffer the whole output.

But this solution breaks the caching of wp-super-cache and no supercache-files are generated when i upload the mu-plugin.

So: If you are using wp-super-cache, you can use the filter of this plugin like this:

add_filter('wp_cache_ob_callback_filter', function($buffer) {
    $buffer = str_replace('foo', 'bar', $buffer);
    return $buffer;
});
查看更多
一纸荒年 Trace。
4楼-- · 2019-01-10 10:27

I have run into problems with this code, as I end up with what seems to be the original source for the page so that some plugins has no effect on the page. I am trying to solve this now - I havnt found much info regarding best practises for collecting the output from wordpress.

Update and sollution:

The code from KFRIEND didnt work for me as this captures unprocessed source from wordpress, not the same output that ends up in the browser infact. My sollution is probably not elegant using a globals variable to buffer up the contents - but atleast I know get the same collected HTML as is delivered to the browser. Could be that different setups of plugins creates problems but thanks to code example by Jacer Omri above I ended up with this.

This code is in my case located typically in functions.php in theme folder.

$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');
查看更多
等我变得足够好
5楼-- · 2019-01-10 10:27

Modified https://stackoverflow.com/users/419673/kfriend answer.

All code will be on functions.php. You can do whatever you want with the html on the "final_output" filter.

On your theme's '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); 
});
查看更多
登录 后发表回答