The Zend Framework Bootstrap made simple (wrap up)
The Zend Framework Bootstrap can be one of the key aspects of getting up and running quickly with the Zend Framework. Let’s make it easy.
Ok, we’ve established that with the Zend Framework, we need to do a bit more work than some of the other frameworks to get up to speed - but that’s not necessarily a bad thing - right?! But it can be a bit tedious and it’s something as professional developers, we want to automate away. So we’ve been addressing in this series how to do just that with a custom, extendable bootstrap class.
In the first part of the series we laid the foundation of our custom bootstrap class by creating a custom class directory structure, adding its namespace to the application ini and modifying the default application bootstrap so that it extends from it and had a look at the first component - caching.
Then, in the second part of the series, we built on the foundation laid in part one by creating plugin resources for the routing table, application navigation and the database connections - these being some of the most common tasks, usually, associated with a web-based application.
In this, the third and final part of the series, I’m going to finish up by looking at application placeholders and surprise, no not logging as originally promised, but pagination. As an added extra, we’re going to be using a key feature of Zend Application to make it a breeze.
Ok, we’ve established that with the Zend Framework, we need to do a bit more work than some of the other frameworks to get up to speed - but that’s not necessarily a bad thing - right?! But it can be a bit tedious and it’s something as professional developers, we want to automate away. So we’ve been addressing in this series how to do just that with a custom, extendable bootstrap class.
In the first part of the series we laid the foundation of our custom bootstrap class by creating a custom class directory structure, adding its namespace to the application ini and modifying the default application bootstrap so that it extends from it and had a look at the first component - caching.
Then, in the second part of the series, we built on the foundation laid in part one by creating plugin resources for the routing table, application navigation and the database connections - these being some of the most common tasks, usually, associated with a web-based application.
In this, the third and final part of the series, I’m going to finish up by looking at application placeholders and surprise, no not logging as originally promised, but pagination. As an added extra, we’re going to be using a key feature of Zend Application to make it a breeze.
So with that, let’s begin!
So what are placeholders? If you’re not familiar with them, the Zend Framework manual describes them this way:
Placeholders allow you to aggregate content, and then render that aggregate content elsewhere.
In short, instead of say, putting raw text for the name of your site or application, your *contact email address *or telephone number throughout your site - creating a nightmare for you (or someone else) to maintain, you create a placeholder, fill it with the desired content, then reference the placeholder throughout your site. Now, when you change the content of the placeholder, you automatically change the content in the rest of your site.
The second benefit of using placeholders, is that they’re easier to find (think grep, et al) as they’re referred to consistently throughout your application. We can have placeholders for all sorts of content, not just simple text. We can also create sidebars - that change dependent on condition, such as site subsection, user role, seasonal festivals and so on. So how do we create them?
Ok, to make the process a bit simpler, we’re going to create a custom resource plugin. How does is this so? Because when we’re done all we’re going to need to do to create any number of placeholders for our application is to list them with a &‘resources.
Start by adding the following snippet to your application.ini. If you reload the application after you save the file, zend will complain that the plugin’s class is not available - so please be patient.
[php] Application placeholders resources.placeholder.application.name = “My Application” resources.placeholder.application.contactEmail = contact@yourapplication.com resources.placeholder.application.url = http://www.yourapplication.com [/php]
With the snippet above, we’re defining three placeholders in a group called application, that’s going to be for application wide settings. The settings will contain the name, contact email and url of a fictitious site. Now that that’s done, let’s have a look at the resource plugin.
Here is the class definition for our new placeholder resource plugin class
[php] class MaltBlue_Application_Resource_Placeholder extends Zend_Application_Resource_ResourceAbstract { protected $_placeholders; protected $_view;
public function init() { $this—>_initPlaceholders(); }
protected function _initPlaceholders() { $options = $this->getOptions();
if (!empty($options)) { // ensure view is initialized… $this->getBootstrap()->bootstrap(&‘view’);
// Get view object: $view = $this->getBootstrap()->getResource(&‘view’);
foreach ($options as $placeholderName => $placeholderConfig) { foreach ($placeholderConfig as $key => $value) { $view->placeholder($placeholderName)->$key = $value; } } }
return $this->_view; } } [/php]
Given our needs are rather simple, this class doesn’t need to be too complex. We create a function _initPlaceholders, which is called in the main init method when our class is loaded.
In the function, we retrieve any options that have been specified for this plugin from the application.ini. If there are any, then we attempt to gain access to the application view resource so that we can create our placeholders. If we’re successful in getting access to the view object, we iterate through each group of placeholder directives and create them as specified.
Once we’re done, we return the view object, should it be needed later.
Now, all this is fine and dandy, but we haven’t made the class available to the bootstrap yet. So, in your application.ini, add the following lines:
[php] ; make the plugin available pluginPaths.MaltBlue_Application_Resource = “MaltBlue/Application/Resource”
[/php]
Now our new class is available and will be used when the bootstrap encounters the new application directives. You can now reload your application and begin using the placeholders in your application view scripts.
Ok, what would a good tutorial be, without an example on how to use them. In our default layout view script, add in the following line:
[php]
placeholder(&'application')->contactEmail; ?>
[/php]Now, when you reload the page, you’ll see the email address you specified earlier being output.
I appreciate that I said, in the first part of the series, that it would end with talking about logging, but since writing that, I remembered that logging’s all taken care of with the Log resource plugin that ships with Zend Framework. So it seems pointless to rehash it. In light of that, I’m going to end this series by creating a resource plugin and method to initialise pagination with Zend Paginator instead.
As you may know, Zend Paginator is quite a configurable resource. It supports a series of configuration options for such things as:
This makes Zend Paginator really flexible and usable in nearly any type of application. Well with the resource plugin and method that follow, we’re going to be able to set all of these options just as simply as we configured placeholders. But to do this, we’re going to need five things:
So let’s have a look at all of the four components mentioned.
The resource plugin class starts by setting three defaults, one for the scrolling type, one for the records per/page and one for the cache key. As with the placeholder class, we do most of the legwork in a sub-method, in this case _initPaginator, which is called in init() when the class is instantiated.
Also as before, we retrieve any configuration directives specified and then start to use them, or the defaults if none were set for the appropriate values. We start by providing a cache for the paginator, then set the scrolling type, then the records per/page, and finish up by specifying the view partial script to use to display the output.
[php] class MaltBlue_Application_Resource_Paginator extends Zend_Application_Resource_ResourceAbstract { const DEFAULT_SCROLLING_TYPE = &‘Sliding’;
const DEFAULT_RECORDS_PER_PAGE = 10;
const PAGINATOR_CACHE = &‘paginator’;
public function init() { $this->_initPaginator(); } protected function _initPaginator() { $options = $this->getOptions();
if (array_key_exists(&‘cache’, $options) && $options[&‘cache’]) { // ensure the cache is initialized… $this->getBootstrap()->bootstrap(&‘cachemanager’);
// get the cache manager object $manager = $this->getBootstrap()->getResource(&‘cachemanager’);
// get the paginator cache object $cache = $manager->getCache(self::PAGINATOR_CACHE);
if (!is_null($cache)) { Zend_Paginator::setCache($cache); } }
if (!empty($options[&‘scrollingType’])) { Zend_Paginator::setDefaultScrollingStyle( $options[&‘scrollingType’] ); } else { Zend_Paginator::setDefaultScrollingStyle( self::DEFAULT_SCROLLING_TYPE ); }
if (!empty($options[&‘recordsPerPage’])) { Zend_Paginator::setDefaultItemCountPerPage( $options[&‘recordsPerPage’] ); } else { Zend_Paginator::setDefaultItemCountPerPage( self::DEFAULT_RECORDS_PER_PAGE ); }
if (!empty($options[&‘viewScript’])) { Zend_View_Helper_PaginationControl::setDefaultViewPartial( $options[&‘viewScript’] ); } } [/php]
In the controller action, we instantiate our paginator - in this case, from an array that has values from 1 - 50. We then grab the current page number from the route, so that we know where in our list of pages we are and therefore need to display. We pass the current view object to the paginator and set it in the view. Now, we’re right to render it in our view script.
[php] $paginator = Zend_Paginator::factory(range(1, 50)); $paginator->setCurrentPageNumber($this->_getParam(&‘page’, 1)); $paginator->setView($this->view); $this->view->paginator = $paginator; [/php]
As we needed to know in the controller action, which page we’re on, then it’s best to make this as simple as possible with a custom route. The one below does that by specifying a page parameter, which, if not specified, defaults to 1.
[php] ; simple users page routes.users-list.type = “Zend_Controller_Router_Route” routes.users-list.route = users/:page routes.users-list.defaults.module = default routes.users-list.defaults.controller = index routes.users-list.defaults.action = index routes.users-list.defaults.page = 1 routes.users-list.reqs.page = \d+ [/php]
You can download it here. We don’t do much special here. We check if there are any records to display in our paginator and if so, iterate over them. At the end, since we’ve given the current view object to our paginator and specified the view script partial, all we need to do is finish up by echoing out the paginator and the pagination control is displayed. No more hard work on our part.
The pagination view script partial is taken directly from the search paginator in the zend framework manual. So I’ll let it cover it best.
Finally, we have the configuration directives. Nice and simple. We have one for all of the defaults previously mentioned.
[php] resources.paginator.cache = true resources.paginator.scrollingType = sliding resources.paginator.recordsPerPage = 10 resources.paginator.viewScript = &‘pagination/default_paginator.phtml [/php]
Now, we’ve done all the leg work required and have simple to use pagination in any of our controller actions. Just four directives along with the accompanying controller action and view script and huzzah - beautiful pagination. What could be simpler?
I apologise for ending differently than initially stated and hope that you don’t feel let down by this change of events. As this was such a lengthy set of posts, covering such an important section of the Zend Framework, I’d love to get your feedback in comments and via twitter. So please comment and tweet. Hear from you soon.
The Zend Framework Bootstrap can be one of the key aspects of getting up and running quickly with the Zend Framework. Let’s make it easy.
In the first part of the series, you’ll remember that we laid the foundation of our custom bootstrap class by creating a custom class directory structure, adding its namespace to the application ini and creating our custom bootstrap file that our application bootstrap will extend from.
After we did that, we put in the first but arguably the most important plugin resource – caching and stored it in the application registry. In this post we’re going to be building on that work and adding in three new plugin resources: routing, navigation and databases.
When you’re creating a new project with the Zend Framework, unlike other frameworks, you need to do more legwork. This isn’t necessarily a bad thing, but it can sure slow you down when you’re trying to plough through a project.
I really enjoy using it, as it has a very well structured approach – and I like structure – it clearly lays out a file-system structure for modules, controllers, actions, forms, models and so on. It has good, but basic, tooling, allowing for modest project initialisation. But despite all this, it still requires a healthy investment on our part to get a proper foundation in place to use it productively.
In a recent project I encountered this situation and felt that I mustn’t be the only one to do so. As I plan to keep using Zend Framework I want to work around this situation and get as much productivity out of it as possible right from the get go. But how to do this?
Well the primary focus for me is bootstrapping. It provides the majority of the core services that every project needs, from routing, data source connections, authentication, authorisation, navigation, caching and so on. So it stands to reason that it’s a good place to start. So I want to cover what should go in to a good working bootstrap.
Recently I was asked how to rename a file with the Zend Framework that used a Zend Form and Zend File element. They key requirement was that it should not be a hack or a kludged solution. So I thought I’d write a quick post to provide a simple example on how it was achieved.
Please consider buying me a coffee. It really helps me to keep producing new tutorials.
Join the discussion
comments powered by Disqus