Zend Framework Tutorial Part 2 ( UI Components with Site Layout, Site Navigations and Forms )
Tuesday, April 8th, 2008In this part of our tutorial we will be building our application's front end ( default module ), constructing the links, creating and validating a form and using FlashMessenger to form errors.
Let's take a look at some of the pages in our application.
“Home” and “About Site” just displays a static page and thus we haven't included “About Site” page in our screenshots. The other two, “Register” and “Login”, includes a form for the user to fill-up and for us to validate.
Our directory structure for our default module will be like the screenshot below.
The uniformity of our pages look was done through our use of Zend_Layout, one of the most useful feature, in building a web application.
In our previous post, we declared in pur bootstrap file that we will be using MVC for our aplication and defined the directory our template files. So, Let's take a look at the important part our template file ( templates/front.phtml ), the full source code of our working applicatio can be downloaded at the end of our tutorial.
1.) The code below creates the title tag in our html part ( including the title tag itself ). The prepend method tells that we will insert the string “ZF Connections” in or every page and adds a separator of “::”. We could see the effect of this on the screenshots displayed above.
$this->headTitle()->prepend('ZF Connections'); $this->headTitle()->setSeparator(' :: '); echo $this->headTitle();
2.) The next code below includes the css files in our application. It will insert all of the necessary attributes for a valid inclusion of css file.
echo $this->headLink() ->appendStylesheet($this->baseUrl . '/styles/blueprint/screen.css', 'screen') ->appendStylesheet($this->baseUrl . '/styles/blueprint/print.css', 'print') ->appendStylesheet($this->baseUrl . '/styles/zf.css', 'screen')
3.) The folowing just includes the necessary files located at the same directory as our template file.
<?php echo $this->partial('front-top-lang.phtml') ?> <?php echo $this->partial('front-header.phtml') ?> <?php echo $this->partial('front-footer.phtml') ?>
4.) The following is a little bit different than the previous one, for it wil loop the content of the parameter passed.
<?php echo $this->partialLoop('front-navigation.phtml', $this->urls) ?> // font-navigation.phtml contains the following <a href="<?php echo $this->url ?>"><?php echo $this->name ?></a> | // and urls is declared in the basecontroller as private function getLinks() { $url = $this->getHelper('Url'); return array( array('name' => 'Home', 'url' => $url->url(array('controller' => ''))), array('name' => 'About Site', 'url' => $url->url(array('controller' => 'about-site'))), array('name' => 'Register', 'url' => $url->url(array('controller' => 'register'))), array('name' => 'Login', 'url' => $url->url(array('controller' => 'login'))) ); } //and set on the init method $this->view->urls = $this->getLinks();
5.) The most important and the simplest part of our layout will be displaying the actual content of the controller called.
<?php echo $this->layout()->content; ?>
We have seen the layout.phtml and now its time to delve into our controlelr classes.
We will discuss the abstract BaseController class upon which all of our controllers on our default module extends upon. BaseController does the work of initializing our FlashMessenger, setting the baseUrl on the view, setting the the layout and links, and other methods.
We have three protected methods on our BaseController class, 1.) validateForm which accepts a Zend_Form instance as its first parameter and the array of data to validate upon, 2.) redirectToController which accepts a controller name and an optional action name as its second parameter, and 3.) addSucessMessage which takes a stirng parameter as message and store it in our flashMessenger.
We have also another helper controller namely the FlashMessagesController. It's only job is to fetch all the messages stored on our FlashMessenger and display it as well as parse upon which kind of message is stored ( success, notice, or error ). We will be including this action through one of view's helper, namely action helper ( nice name ).
Its only method, indexAction, contains the following code:
if($this->_flashMessenger->hasMessages()) { $display_messages = array(); $messages = $this->_flashMessenger->getMessages(); foreach($messages as $message) { if(substr($message, 0, 4) == 'type') { $type = explode('=', $message, 2); $this->view->messages_type = $type[1]; } else { $display_messages[] = $message; } } $this->view->messages = $display_messages; }
// and this will be the phtml file for displaying our message <?php if($this->messages && is_array($this->messages)): ?> <div class="<?php echo $this->messages_type ?>" style="width:350px" align="left"> <?php if(isset($this->messages[1])): ?> <?php echo $this->formErrors($this->messages) ?> <?php else: ?> <?php echo $this->messages[0] ?> <?php endif; ?> </div> <?php endif; ?>
Our IndexController and AboutSiteController are pretty straightforward and just displays their properly configured view file. We have configured these controller files to load the view file in a separate directory, instead of their default ones. The code looks like the following:
// IndexController ( indexAction ) $this->render('home', null, true); // AboutSiteController ( indexAction ) $this->render('about-site', null, true);
This line of code tells us that we will load the about-site.phtml in top directory of views folder, meaning not under any controller specific subdirectory ( the true argument on render particulary says that the view does not have a controller ). The second argument (null ), simply tells that we will be including all the segment of the response object.
Now we'll have to take a look at our RegisterController. RegisterController does some other things beside displaying the register page. In this controller, we will creae a Zend_Form to be included in the view area, validates our form after submission and displays messages based on the result of validation ( success or error ).
We first take a look at the creation of form defined on the getForm() method on our RegisterController.
$form = new Zend_Form(); $form->setAction($this->_request->getBaseUrl() . '/' . $this->_request->getControllerName() . '/signup') ->setMethod('post'); $email = $form->createElement('text', 'email', array('class' => 'text')); $email->addValidator('EmailAddress') ->setRequired(true) ->addFilter('StringToLower') ->addFilter('StringTrim') ->setLabel('Email Address'); $submit = $form->createElement('button', ' Submit ', array('type' => 'submit', 'class' => 'button')); $form->addElement($email) ->addElement($submit); return $form;
Creating of Zend_Form is pretty straightforwad, the trivial part is the creation of its action. We didn't hard-code the action of our form so that our form will be more flexible and we won't be changing any the form's properties.
Our email element was created through the form's createElement method. We have created a input element with type of text, with name of email and a class of text.
We have added a validator for the element, EmailAddress, or we could have written the validation just like the following instead:
$email->addValidator(new Zend_Validate_EmailAddress());
And we have added some filters, StringToLower and StringTrim, which are quite straightforward. And lastly we have added a label to the element.
The next element on our form is the submit button. we have used button element with type of submit.
After the two elements were created, we have added the two elements back on the form for display.
Our signupAction which do the validation of our form is as simple as the following code:
if(!$this->_request->isPost()) { return $this->redirectToController('register'); } if(!$this->validateForm($this->getForm(), $_POST)) { return $this->redirectToController('register'); } $message = ' Thank you for joining ZF Connections '; $message .= ' Your login credentials will be submitted in the email that you have provided. '; $this->addSuccessMessage($message); return $this->redirectToController('register');
First we, checked is submitted via post method. The next checking is actually checking of forms for theie errors. If the form does not have any errors we just display a message ( for now ). All of the following cases will end up redirecting to the “register” controller.
The validateForm method on our BaseController is defined as follows:
protected function validateForm(Zend_Form $form, array $data) { if(!$form->isValid($data)) { foreach($form->getMessages() as $field => $message) { foreach($message as $error) { $this->_flashMessenger->addMessage(strtoupper($field) . ' ' . $error); } } $this->_flashMessenger->addMessage('type=error'); return false; } return true; }
The method checks the form and add any errors generated and add it to our flashMessenger.
LoginController is almost the same as RegisterController, the only difference is that LoginController has an additional element on its form which is the password element. You can download our working application below and take a look on how we have glued together our application.
Our next topic will be creating a Model for database interaction and finishing up our registration and login. We will be using more ZF classese like Zend_Auth, Zend_Acl, Zend_Log and other classes we may need as we code.
See you next time and happy coding! =)
Download Files Here ( Zend Framework is not included in the zip file dure to file limitation ):
ZF Tutorial Part2 - Files


