Output Filters in Zend_View
A feature of Zend Framework MVC that isn't currently very well documented is output filters. They're mentioned in passing in the Zend_View
documentation, but not reviewed in detail anywhere in the Reference Guide as of version 1.5.2. I was curious enough about how to implement markup minification that I decided to trace through the Zend_View
source code in attempt to discern how output filters actually worked. As it turns out, it's actually pretty simple.
First, you need to get a reference to the current Zend_View
instance. If you're using the Zend_Layout
MVC integration, you can get this by calling $this->
_helper
->
layout
->
getLayoutInstance()
within your Zend_Controller_Action
class to get the current Zend_Layout
instance and then getView()
on that to get your Zend_View
instance. Otherwise, the Zend_View
instance is available via the view
property of Zend_Controller_Action
instance.
Next, call addFilterPath()
or setFilterPath()
on your Zend_View
instance from your Zend_Controller_Action
class. Pass in a path to the directory to contain your output filter classes and a naming prefix that all of your output filter classes will use. I'm not sure why the class prefix defaults to Zend_View_Filter_
since no such classes exist. In my opinion, it would have made more sense to derive the prefix based on the provided directory path. Anyway, create the directory you've specified if it doesn't already exist and create a new class file within that directory. In my case, I named the directory Vendor/View/Filter
, the file Minify.php
, and the class contained in the file Vendor_View_Filter_Minify
.
Within this class, you must implement at least one method, filter()
. This method should accept a single parameter, which will be a string containing the view ouput to be filtered, and should return the filtered version of that string. Optionally, if your filter requires access to the related Zend_View
instance, you can also declare a setView()
method that accepts the Zend_View
instance as its only parameter, and it will automatically be passed in when your output filter class is instantiated. Within setView()
, you can store the Zend_View
instance in an instance property of the output filter class so it can be referred to later in the filter()
method.
Once you've finished your output filter class, you need to explicitly add it to the output filters in use from your Zend_Controller_Action
class. You can use addFilter()
or setFilter()
for this. Pass in the name of your output filter class without the class prefix. In my case, I passed in 'Minify'
. At this point, the filter should be used when rendering your page. I poked around in the DOM and Tidy PHP extension documentation, but couldn't find a feature for markup minification, so I ended up using the PCRE extension to do the job. Below is the final source code for my output filter class.
// Vendor/View/Filter/Minify.php
class Vendor_View_Filter_Minify
{
public function filter($string)
{
return preg_replace(
array('/>\s+/', '/\s+</', '/\[\\x0A\\x0D\]+/'),
array('>', '<', ' '),
$string
);
}
}
// Vendor/Controller.php
class Vendor_Controller extends Zend_Controller_Action
{
public function init()
{
$this->_helper->layout->getLayoutInstance()->getView()
->addFilterPath('Vendor/View/Filter', 'Vendor_View_Filter_')
->addFilter('Minify');
}
}