I recently received an email asking for my advice about how to handle a form that appears on every page.
I want to add a newsletter sign up box to layout.phtml so it will appear on every page. The layout->content() comes from several different action controllers... So how do I handle the newsletter sign up?
I thought that the answer is long-winded enough to be worth writing a blog post about.
One way to do this is to use a action helper, so let's build a simple application to show this solution.
Start by setting up a ZF application:
$ zf create project layoutform $ cd layoutform $ zf enable layout
Copy the Zend Framework's library/Zend folder into layoutform/library check that you get the ZF Welcome screen when you navigate to the project in your browser. Empty application/views/scripts/index/index.phtml and replace with something simple like this:
application/views/scripts/index/index.phtml:
<p>This is the home page</p>
Now we have a clean, simple place to start from.
The form
We need a form, so we'll create one:
$ zf create form signup
Now, let's create the fields we need:
application/forms/Signup.php:
class Application_Form_Signup extends Zend_Form { public $processed = false; public function init() { $this->addElement('text', 'name', array( 'label' => 'Name', 'required' => true, 'validators' => array( array('StringLength', false, array('max'=>75)), ), )); $this->addElement('text', 'email', array( 'label' => 'Email', 'required' => true, 'validators' => array( array('StringLength', false, array('max'=>150)), 'EmailAddress', ), )); $this->addElement('submit', 'go', array( 'label' => 'Sign up', )); } }
now we have a form, we need to instantiate it and then display it.
The action helper
We use an action helper to instantiate the form and then later process it.
Firstly, setup the action helper. add a line to the [production] section of the config file:
application/configs/application.ini:
resources.frontController.actionhelperpaths.Application_Controller_Helper = APPLICATION_PATH "/controllers/helpers"
Now the system knows were we are storing our action helpers, we can register a helper called Signup:
application/Bootstrap.php:
<?php class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initMyActionHelpers() { $this->bootstrap('frontController'); $signup = Zend_Controller_Action_HelperBroker::getStaticHelper('Signup'); Zend_Controller_Action_HelperBroker::addHelper($signup); } }
The action helper looks like this:
application/controllers/helpers/Signup.php:
<?php class Application_Controller_Helper_Signup extends Zend_Controller_Action_Helper_Abstract { public function preDispatch() { $view = $this->getActionController()->view; $form = new Application_Form_Signup(); $request = $this->getActionController()->getRequest(); if($request->isPost() && $request->getPost('submitsignup')) { if($form->isValid($request->getPost())) { $data = $form->getValues(); // process data $form->processed = true; } } $view->signupForm = $form; } }
This is pretty standard code for form handling. The only unusual thing we do is that set the processed property of the form to true so that we know that we have done something. We then use this to display a thank you message.
The view helper
To display the form, we use a view helper which is called from the layout view script.
The view helper looks like this:
application/views/helpers/SignupForm.php:
<?php class Zend_View_Helper_SignupForm extends Zend_View_Helper_Abstract { public function signupForm(Application_Form_Signup $form) { $html = '<h2>Sign up for our newsletter</h2>'; if($form->processed) { $html .= '<p>Thank you for signing up</p>'; } else { $html .= $form->render(); } return $html; } }
And to round it off, we render this in layout.phtml, whilst also taking the opportunity to create a minimal layout script:
application/layouts/scripts/layout.phtml:
<?php $this->headMeta()->prependHttpEquiv('Content-Type', 'text/html; charset=UTF-8'); $this->headTitle('Layout form test'); echo $this->doctype(); ?> <html> <head> <?php echo $this->headMeta()->setIndent(4); ?> <?php echo $this->headTitle()->setIndent(4); ?> </head> <body> <div id="maincontent"> <?php echo $this->layout()->content; ?> </div> <div id="secondary"> <?php echo $this->signupForm($this->signupForm); ?> </div> </body> </html>
All done
And that's it. The form is displayed on every page and if filled in, it is processed and a thank you message is displayed. Obviously validation also works.
Completely un-styled, it looks like this:

This is the project code that I used: zf-tutorial-layoutform.zip
if you found this useful, then you should have a read of Matthew's article on using action helpers to implement re-usable widgets also.



