Tidy Output Filtering

By Matthew Harris (kuja)
If you'd like to filter all output from your application (layouts and views) through Tidy for cleaner markup, then this article is for you!
I recently stumbled across an urge to output clean HTML/XHTML on all my pages without having to worry much about writing the actual markup. Being able to do this would allow me to generate clean markup in all cases (at the cost of performance, of course).

Now, before starting, please note that you will need the php-tidy extension. You can read more at http://php.net/tidy.

Now, onto the good stuff. The solution I came to (thanks to AD7six) was creating a helper. I called this the TidyFilterHelper (I thought that TidyHelper may have been a bit misleading in this case).

You simply create the tidy_filter.php helper file, drop it in APP/views/helpers/.

The code is as follows:

Helper Class:

Download code <?php 
class TidyFilterHelper extends AppHelper {
    function 
__construct()
    {
        
ob_start();
    }
    
    function 
__destruct()
    {
        
$output ob_get_clean();
        
$config = array('indent' => true'output-xhtml' => true);
        
$output tidy_repair_string($output$config'utf8');
        
        
ob_start();
        echo 
$output;
    }
}
?>


Now that is pretty cool. It would've been cooler if Helper::afterLayout() was a working callback (it's defined in Helper, it's documented, just not implemented as a callback yet.. but it will be soon!)

Now that you've got the helper in place, all you need to do is add the appropriate entry into your AppController::$helpers array, if you want to apply it to absolutely all output.

If you still don't understand, try this:

Controller Class:

Download code <?php 
class AppController extends Controller {
    var 
$helpers = array('TidyFilter''...some of your other helpers...');
}
?>


Everything will now work automatically.

Happy baking!

 

Comments 684

CakePHP Team Comments Author Comments
 

Comment

1 Nice

Thanks for writing this article. I wanted to suggest also that if someone was adding this functionality to an application that they wanted to be more portable, perhaps it would be a good idea to add something along the lines of if(class_exists('Tidy')), to avoid notices if Tidy wasn't installed/enabled in a target environment.
Posted May 21, 2008 by Tim MacAleese aka Sliv
 

Comment

2 A Modified Approach

Here's a modified approach to your helper that I'm trying out:

http://bin.cakephp.org/view/744338418
Posted May 21, 2008 by Tim MacAleese aka Sliv
 

Comment

3 CakePHP limitation

@kuja: nice idea! Instead of doing the work in the __destruct you may wish to do it on the afterRender() method of the helper.

That would be the ideal location to stick the code, but unfortunately due to Cake's output buffering, this was the only way to do it!
Posted May 23, 2008 by Matthew Harris
 

Comment

4 Can we Cache this

Here's a modified approach to your helper that I'm trying out: http://bin.cakephp.org/view/744338418


Very nice Sliv, thanks for exposing the additional config that Tidy offers (I had not heard of this extension before).

Would there be any way of caching this process as I can imagine it's a pretty CPU intensive process.
Posted May 27, 2008 by Jonny Reeves
 

Comment

5 Very nice

This is def very cool and simple! Thanks!

In my current project I don't see much of a performance decrease at all.
Posted Jun 3, 2008 by Chey