The magic of view helpers
by Naneau
It has been a while since I’ve written on my blog, so it’s about time I give you all an update. I thought I’d start with something fun: view helpers.
Even for those of you who don’t always find joy in programming, view helpers might just make you happy. They can really make some of the more annoying tasks, like the ones where you have to switch in and out of PHP context, a lot easier.
In it’s most basic form a view helper looks like this:
1 2 3 4 5 | class Naneau_View_Helper_SomeHelperName { public function someHelperName() { return 'Hello, cruel world!'; } } |
As you an see, the class does not have to extend any base class, like action helpers and plugins do. There’s just one public function in there, which shares the name of the class (except it’s first letter isn’t capitalized). When the helper gets called from your view, an object of this class gets initialized, and the function is executed.
That’s all there is to it. You write a small class, and put a single function in there, it couldn’t be any easier. From your view you can call it like:
1 2 3 4 5 6 | <?php echo $this->someHelperName(); //creates object of class Naneau_View_Helper_SomeHelperName //calls function someHelperName() //echos result 'Hello, cruel world!' ?> |
Now, while single function view helpers can help you avoid a lot of repetition and ugly mixed php/html code, there is a limit to what you can do with just one function. Sometimes you just want to add more logic to your class. For instance, say that you want to count something, and display the result. You would want to have a method for adding, and a method for displaying the result. There is a neat little trick to accomplish this using view helpers:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | class Naneau_View_Helper_CounterHelper { /** * a counter * @var int */ private $_counter = 0; /** * get the helper instance * @return Naneau_View_Helper_CounterHelper */ public function counterHelper() { return $this; //return this object (for chaining) } /** * add to the counter * @param int $howMuch * @return void */ public function add($howMuch = 1) { $this->_counter += $howMuch; } /** * get the result * @return int */ public function result() { return $this->_counter; } } |
If you look at the “original” helper method “counterHelper()”, you can see that it returns $this. This allows you to chain the result to other methods in your view:
1 2 3 4 5 6 7 8 9 | .. this is a view ... <?php $this->counterHelper()->add(1); ?> ... view stuff here ... <?php $this->counterHelper()->add(2); ?> ... some more view stuff ... <?php echo $this->counterHelper()->result(); //will output 3 ?> |
Now, there is one more thing you should know about view helpers. Sometimes you want to call one helper from another. This is possible by accessing the view object the helpers work on. As soon as you call a view helper from a view, it tries to call setView() on the helper, passing itself (the current view object) as a parameter. This means you can retrieve that object by adding the method to your helper:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class Naneau_View_Helper_Composed { /** * the view object * @var Zend_View */ private $_view; /** * set the current view * @param Zend_View $view */ public function setView($view) { $this->_view = $view; } /** * the main helper method, uses the counter helper * @return int */ public function composed() { $this->_view->counterHelper()->add(10); $this->_view->counterHelper()->add(5); //assume this is something useful ;) return $this->_view->counterHelper()->result(); } } |
Which you could use like:
1 2 3 4 | <?php echo $this->composed(); //will output 15 ?> |
Comments
I like the “return $this” trick, great job my little bunny
return $this; is a very neat one, thanks
Interesting as usual. Please, I encourage you to post more often! Your insight is clear and helpful. I have certainly gained significant knowledge from your writings and am very appreciative of the time you put into this blog. Keep up the good work.
well, I would more appreciate some library of already created view helpers. Like I was doing calendar helper -> input type=”text” with integrated javascript calendar, Zend_Date compatible. Or array from DB -> html table generator. Such waste of time. Stuff like that is desperadly needed in ZF. I dont want to write no more helpers if I dont have to
Been missing your posts, glad you’re “back”
Yeah! Keep on posting! Very helpful (again!)
We just talked on #ZFtalk and I commented on ‘my way’ of getting one Ziew_Helper talking to another View_Helper.. I was using:
Zend_Controller_Action_HelperBroker::getStaticHelper(‘viewRenderer’)->view
To get the view object back, and from there could call:
Zend_Controller_Action_HelperBroker::getStaticHelper(‘viewRenderer’)->view->HelperName()
[ I considered always sending the view object by reference view as a parameter to the helper function View_Helper($view, $parameters) but that seemed too much work to be logical. I didn;t know about the setView() function that's great! Thanks a lot for your posts ]
You saved my ass! I was ready to give up on helpers I came across your post.
[...] you start writing view helpers you’ll probably put them in the “helpers” subdirectory of your “views” directory. This is [...]
Абсолютно согласен с 1ым ответом. Оно того стоит…
Большое спасибо. Появилась новая мысль, но она потребует сильной реорганизации моей идеи, займусь в выходные. Скоро поделюсь с читателями блога!