How To Filter The Whole Page In WordPress
WordPress has numerous hooks for filtering posts, comments, feed items and more, but no built-in filter that would let you intercept and modify an entire page. However, you can do that fairly easily with PHP’s output buffering functions. Today I’m going to show you how.
Crash-Course In Output Buffering
As the name implies, output buffering lets you buffer the output of a PHP script. Once you initialize a buffer using the ob_start()
function, any output that would normally be sent to the browser is stored in the buffer instead (exception : HTTP headers are still sent immediately). You can then process the buffer’s contents and send a modified version to the browser, or discard the buffer entirely if you like. PHP will also automatically flush any active buffers at the end of the script’s execution.
One of the ways to manipulate the output is to create a callback function that takes the current contents of the buffer and returns a new buffer. Then you just pass the function name to ob_start()
and it will be automatically called when the buffer is flushed or cleaned. This is the method that we’ll use to filter WP-generated pages.
Filtering WordPress Pages
Enough with theory, lets see some code! Here’s a simple example plugin that uses output buffering to attach the current URL and page size to each page generated by WordPress :
<?php /* Plugin Name: Page Filter Example Plugin URI: http://w-shadow.com/blog/2010/05/20/how-to-filter-the-whole-page-in-wordpress/ Description: Demonstrates how to filter the entire page in WordPres. Version: 1.0 Author: Janis Elsts Author URI: http://w-shadow.com/ */ /** * Initialize output buffering. */ function ws_set_up_buffer(){ //Don't filter Dashboard pages and the feed if ( is_feed() || is_admin() ){ return; } //Start buffering. Note that we don't need to //explicitly close the buffer - WP will do that //for use in the "shutdown" hook. ob_start('ws_filter_page'); } add_action('wp', 'ws_set_up_buffer', 10, 0); /** * Buffer callback. * * @param string $html Current contents of the output buffer. * @return string New buffer contents. */ function ws_filter_page($html){ //As an example, lets append the current URI //and page size to the generated HTML. $info = sprintf( "<!-- \nPage : %s\nHTML size : %d bytes\n -->", $_SERVER['REQUEST_URI'], strlen($html) ); return $html . $info; } ?>
Tips and Notes
There are some things to keep in mind when using output buffering to filter WordPress pages.
- You probably don’t want to filter each and every page. For example, the Dashboard and the RSS feed should most likely be excluded (unless you’re specifically targeting them, of course). Use conditional tags to check whether the current request refers to one of those pages.
- Many conditional tags won’t work properly until after WP has finished parsing the current request. To mitigate this, attach your buffer initialization routine to an action that runs after the query has already been parsed. The “wp” action is a good choice.
- You don’t need to explicitly close/flush your output buffer – WordPress will do that automatically. See
wp_ob_end_flush_all()
in/wp-includes/functions.php
. - Beware of conflicts with optimization-related plugins. To make pages load faster, some of them will set up their own buffer and compress page contents with the gzip algorithm. This can make those pages appear as unreadable gibberish to your script. To avoid that, make sure your buffer is initialized after the other plugin’s buffer. Some hook priority tweaking may be required.
And now you know how to filter the whole WP page 🙂
Related posts :
[…] W-Shadow for his ‘How to filter whole pages in WordPress‘ […]
[…] Das ganze basiert auf der Möglichkeit, den gesamten Output von WordPress zu puffern, wie es auf W-Shadow.com gezeigt wird. […]
[…] with a howto on wholepage filtering published on w-shadow.com, I ended up with a compact piece of code that can be inserted into an generic wordpress plugin: […]
What’s up everyone, it’s my first visit at this web site, and
post is actually fruitful in favor of me, keep up posting these
types of posts.