Creating Re-Usable Zend_Application Resource Plugins
In my last article,
I wrote about how to get started with Zend_Application
, including some
information about how to write resource methods, as well as listing available
resource plugins. What happens when you need a re-usable resource for which
there is no existing plugin shipped? Why, write your own, of course!
All plugins in Zend Framework follow a common pattern. Basically, you group plugins under a common directory, with a common class prefix, and then notify the pluggable class of their location.
For this post, let's consider that you may want a resource plugin to do the following:
- Set the view doctype
- Set the default page title and title separator
Getting Started
First, let's determine the class prefix we want to use. If we follow Zend Framework Coding Standards, we can leverage autoloading, while simultaneously ensuring a common class prefix for our resources.
For the purposes of this exercise, we'll use the class prefix Phly_Resource
, located in Phly/Resource/
on our include_path
.
We'll call our particular resource "Layouthelpers", with a full class name of Phly_Resource_Layouthelpers
, and place it in Phly/Resource/Layouthelpers.php
. It needs to implement Zend_Application_Resource_Resource
, but it's often even easier to extend Zend_Application_Resource_ResourceAbstract
. In both cases, you need to define an init()
method. Let's set up our skeleton accordingly:
<?php
// Phly/Resource/Layouthelpers.php
//
class Phly_Resource_Layouthelpers
extends Zend_Application_Resource_ResourceAbstract
{
public function init()
{
}
}
On Dependency Tracking
In my previous article, I showed an example of dependency tracking in
Zend_Application
. We will need it in this exercise as well, as both of our
tasks operate on the view object, which we will retrieve via the View resource.
When creating resource methods directly in your bootstrap, you can simply call
$this->getResource($name)
. However, within a plugin resource class, you need
to first get access to the bootstrap object itself — which you can do with the
getBootstrap()
method.
Let's ensure the View resource is initialized, and retrieve it.
<?php
// Phly/Resource/Layouthelpers.php
//
class Phly_Resource_Layouthelpers
extends Zend_Application_Resource_ResourceAbstract
{
public function init()
{
$bootstrap = $this->getBootstrap();
$bootstrap->bootstrap('View');
$view = $bootstrap->getResource('View');
// ...
}
}
Configuring the resource
Now that we've got our view object, we can do some work. Since we want the
resource to be re-usable, we should likely allow some configuration options.
Zend_Application_Resource_ResourceAbstract
provides some boilerplate
functionality for doing so.
First, we'll provide some default options via the $_options
property.
<?php
// Phly/Resource/Layouthelpers.php
//
class Phly_Resource_Layouthelpers
extends Zend_Application_Resource_ResourceAbstract
{
protected $_options = array(
'doctype' => 'XHTML1_STRICT',
'title' => 'Site Title',
'title_separator' => ' :: ',
);
public function init()
{
$bootstrap = $this->getBootstrap();
$bootstrap->bootstrap('View');
$view = $bootstrap->getResource('View');
// ...
}
}
We can then grab options using the getOptions()
method.
<?php
// Phly/Resource/Layouthelpers.php
//
class Phly_Resource_Layouthelpers
extends Zend_Application_Resource_ResourceAbstract
{
protected $_options = array(
'doctype' => 'XHTML1_STRICT',
'title' => 'Site Title',
'title_separator' => ' :: ',
);
public function init()
{
$bootstrap = $this->getBootstrap();
$bootstrap->bootstrap('View');
$view = $bootstrap->getResource('View');
$options = $this->getOptions();
// ...
}
}
Now, in configuration files, developers can override the defaults:
[production]
; ...
resources.layouthelpers.doctype = "HTML5"
resources.layouthelpers.title = "My Snazzy New Website"
resources.layouthelpers.title_separator = " &emdash; "
Doing some work
Now that we have the bits and pieces of naming and configuration out of the way, let's do some work:
<?php
// Phly/Resource/Layouthelpers.php
//
class Phly_Resource_Layouthelpers
extends Zend_Application_Resource_ResourceAbstract
{
protected $_options = array(
'doctype' => 'XHTML1_STRICT',
'title' => 'Site Title',
'title_separator' => ' :: ',
);
public function init()
{
$bootstrap = $this->getBootstrap();
$bootstrap->bootstrap('View');
$view = $bootstrap->getResource('View');
$options = $this->getOptions();
$view->doctype($options['doctype']);
$view->headTitle()->setSeparator($options['title_separator'])
->append($options['title']);
}
}
And that's it!
Telling the Bootstrap about us
Well, that's it for the plugin resource, that is. But how do we tell our bootstrap class about it? Via our configuration file, using the "pluginPaths" key. This is an array, with the keys being plugin class prefixes, and the values the path that corresponds to that prefix.
[production]
; ...
pluginPaths.Phly_Resource = "Phly/Resource"
resources.layouthelpers.doctype = "HTML5"
resources.layouthelpers.title = "My Snazzy New Website"
resources.layouthelpers.title_separator = " &emdash; "
You can register as many plugin paths as you desire. As this key is processed before any resources are processed, it can also be defined at any time in your configuration.
Further Considerations
The example in this post was admittedly trivial. One aspect not discussed was
creating a resource that would be reused throughout your application. As an
example, you might want to create a resource you'll use at different times in
your application. If you return a value in your init()
method, the bootstrap
object will store this for later retrieval. A good example of this we saw
earlier: the View resource registers a Zend_View
object with the bootstrap
simply by returning the instance from its resource plugin.
Conclusions
Hopefully this post and the post prior have helped shed some light on
Zend_Application
, and in particular, how to write and bootstrap resources.
If you have further questions, you can find me on the ZF mailing lists, on IRC via the Freenode servers, or on twitter. Good luck!