Welcome to Abdul Malik Ikhsan's Blog

Zend Framework 2 : Create Your Custom View Helper

Posted in Tutorial PHP, Zend Framework 2 by samsonasik on July 20, 2012

In MVC Architecture, sometimes, we have to do a “logic” to manage a view. The Logic is called by View named View Helper. Zend Framework 2 has a ton of flexibility, so, we can create a custom View Helper if we want to -that can be called by View Layer over modules.

For Example, i want to create a View Helper named Testhelper which the responsibility of this helper is to state that the string is found or not.  First of all, we create a Helper under src directory :
And the content of Testhelper is :

namespace Test\View\Helper;
use Zend\View\Helper\AbstractHelper;

class Testhelper extends AbstractHelper
{
    public function __invoke($str, $find)
    {
        if (! is_string($str)){
            return 'must be string';
        }

        if (strpos($str, $find) === false){
            return 'not found';
        }

        return 'found';
    }
}

The next step is register that in Module.php

namespace Test;

use Zend\ModuleManager\Feature\AutoloaderProviderInterface,
    Zend\ModuleManager\Feature\ConfigProviderInterface,
    Zend\ModuleManager\Feature\ViewHelperProviderInterface;    

class Module implements 
    AutoloaderProviderInterface, 
    ConfigProviderInterface, 
    ViewHelperProviderInterface
{
    public function getAutoloaderConfig(){/*common code*/}
    public function getConfig(){ /*common code */ }

    public function getViewHelperConfig()
    {
        return array(
            'factories' => array(
                'test_helper' => function($sm) {
                    $helper = new View\Helper\Testhelper ;
                    return $helper;
                }
            )
        );   
   }
}

OR, you can SIMPLIFY that by configuring it as an invokable in module.config.php as @weierophinney ( project lead for Zend Framework ) suggestion -thanks a lot for his suggestion- like this :

return array(
//.........
    'view_helpers' => array(
        'invokables'=> array(
            'test_helper' => 'Test\View\Helper\Testhelper'   
        )
    ),
//.........
);

Last step, call it in the view :

echo $this->test_helper("me","e");
About these ads

59 Responses

Subscribe to comments with RSS.

  1. Juanito Perez said, on September 27, 2012 at 7:11 am

    Excelent tutorial bro!! I’m learning ZF2 and your site is very good.

  2. samsonasik said, on October 5, 2012 at 11:31 am

    Thank you ;)

  3. Dragan Menoski said, on October 16, 2012 at 3:41 pm

    Great job !
    Thank you

  4. samsonasik said, on October 16, 2012 at 4:32 pm

    You’re welcome ;)

  5. loktheprince said, on December 5, 2012 at 1:58 pm

    $this->paginationControl($albums, ‘Sliding’, ‘pager.phtml’, array(‘lang’=>’en’)) is not working for me.
    $this->pageCount dont have any value
    $this->getRequest()->getServer()->get(‘QUERY_STRING’) is not returning anything

    Please suggest me

  6. [...] post about creating Controller pLugin in ZF2. For what have to do to create a View Helper , see : my post about creating view helper or EvanDotPro’s [...]

  7. Guilhem said, on January 10, 2013 at 5:07 am

    Thanks for that and happy new year :)

  8. piasek said, on January 25, 2013 at 8:50 pm

    Hi
    I’m trying to create my View Helper where i will create IMG tag
    so far i have this:

    <?php
    
    // module/Photo/src/Photo/View/Helper/ImgHelper.php
    
    namespace Photo\View\Helper;
    
    use Zend\View\Helper\AbstractHelper;
    
    class Imghelper extends AbstractHelper
      {
        protected $_baseUrl = null;
        protected $_exists = array();
    
        public function __construct ()
          {
            $url = PUBLIC_PATH;
            $root = '/' . trim($url, '/');
    
            if ($root == "/")
              {$root = "";}
    
            $this->_baseUrl = $root . "/";
          }
    
        public function img($path, $params = array())
          {
            $plist = array();
            $str = null;
    
            $imgpath = $this->_baseUrl . ltrim($path);
    
            if (!isset($this->_exists[$path]))
              {$this->_exists[$path] = file_exists(realpath($imgpath));}
    
            if (!isset($params['alt']))
              {$params['alt'] = '';}
    
            foreach ($params as $param => $value)
              {$plist[] = $param . '="' . $this->view->escape($value) . '"';}
    
                    $str = " ".join(" ", $plist);
            $p = ($this->_exists[$path]) ? $this->_baseUrl.ltrim($path,'/') : null;
    
            if (isset($p))
              {return '<img src="'.$p.'" '.$str.' />';}
          }
    
      } 
    

    But i have an error on line with $this->view->escape($value)
    and the question is how i can get function escape to work here?

    Error message
    “Fatal error: Uncaught exception ‘Zend\ServiceManager\Exception\ServiceNotFoundException’ with message ‘Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for escape’ in ”

    thx

    • samsonasik said, on January 26, 2013 at 12:52 am

      You should extends

      Zend\View\Helper\Escaper\AbstractHelper; 
      

      which Escaper is placed., so the code should be :

      namespace Photo\View\Helper;
      
      use Zend\View\Helper\Escaper\AbstractHelper;
      
      class Imghelper extends AbstractHelper
      {
          protected $_baseUrl = null;
          protected $_exists = array();
      
          public function __construct ()
          {
              $url = PUBLIC_PATH;
              $root = '/' . trim($url, '/');
      
              if ($root == "/")
                {$root = "";}
      
              $this->_baseUrl = $root . "/";
          }
          
          public function escape($value)
          {
             return $this->getEscaper()->escapeHtml($value);
          }
      
          public function __invoke($path, $params = array())
          {
                     $plist = array();
              $str = null;
      
              $imgpath = $this->_baseUrl . ltrim($path);
      
              if (!isset($this->_exists[$path]))
                {$this->_exists[$path] = file_exists(realpath($imgpath));}
      
              if (!isset($params['alt']))
                {$params['alt'] = '';}
      
              foreach ($params as $param => $value)
                {$plist[] = $param . '="' . $this->escape($value) . '"';}
      
                      $str = " ".join(" ", $plist);
              $p = ($this->_exists[$path]) ? $this->_baseUrl.ltrim($path,'/') : null;
      
              if (isset($p))
                {return '<img src="'.$p.'" '.$str.' />';}
          }
        } 
      

      and use $this->getEscaper()->escapeHtml() to escape the html.
      do escapeJs() or other depend on your need.

      so, in the view, you can call :

       echo $this->yourimghelper($path, array());
      
  9. Ioan Katalin said, on February 14, 2013 at 7:14 pm

    use Zend\ModuleManager\Feature\AutoloaderProviderInterface,
    Zend\ModuleManager\Feature\ConfigProviderInterface,
    Zend\ModuleManager\Feature\ViewHelperProviderInterface;

    class Module implements
    AutoloaderProviderInterface,
    ConfigProviderInterface,
    ViewHelperProviderInterface
    {//..
    public function getViewHelperConfig()
    {
    return array(
    ‘factories’ => array(
    ‘Ie9′ => function ($sm) {
    $locator = $sm->getServiceLocator();
    $viewHelper = new View\Helper\Ie9;
    return $viewHelper;
    }
    ),
    );
    }
    //…
    }

  10. Rid Zeal said, on February 24, 2013 at 12:23 am

    Tanya sedikit mas Iksan, kalo untuk dipakai semua module berarti harus di register di invocables di module.config nya ya?

    Apa memungkinkan kalau dibuat di library eksternal, jadi bisa ambil dari situ, tidak perlu register2 lagi.
    Trims.

  11. Juan Rojas said, on March 18, 2013 at 11:43 pm

    Hi, I tried this but get the following error and my application crashes:

    Warning: Class ‘Zend\Stdlib\ArrayObject\PhpReferenceCompatibility’ not found in C:\Program Files (x86)\Zend\ZendServer\data\apps\http\__default__\MT5_0\1.0.0\vendor\zendframework\zendframework\library\Zend\Stdlib\ArrayObject.php on line 24

    Fatal error: Class ‘Zend\Stdlib\AbstractArrayObject’ not found in C:\Program Files (x86)\Zend\ZendServer\data\apps\http\__default__\MT5_0\1.0.0\vendor\zendframework\zendframework\library\Zend\Stdlib\ArrayObject.php on line 33

    Any Ideas? i really like your tutorials by the way.

    • samsonasik said, on March 19, 2013 at 6:00 am

      use ZendSkeletonApplication to be a skeleton project. clone this : https://github.com/zendframework/ZendSkeletonApplication and update your ZF library to the latest master.

      • vikas said, on March 19, 2013 at 6:17 pm

        hello samsonasik i want put search box in my form for search data but i’dont get any easy solution for same and also i am new in zend so can you put tutorial step by step for my help..

      • samsonasik said, on March 20, 2013 at 5:05 pm

        you can create a form to accomodate it. thanks for the suggestion.

  12. Sasha said, on March 26, 2013 at 12:23 am

    Hello, please advice how to use url() helper in custom view helper. Thank you for your time.

    • samsonasik said, on March 26, 2013 at 12:25 am

      you can do something like this :

          public function __invoke()
          {
              $urlHelper = $this->view->plugin('url');
              
              //do other thing...
          }
      
  13. hhh said, on April 27, 2013 at 12:39 am

    how to add a helper to specified module?

    this will apply to all modules ..
    ‘view_helpers’ => array(
    ‘invokables’=> array(
    ‘test_helper’ => ‘Test\View\Helper\Testhelper’
    )
    ),

    • samsonasik said, on April 27, 2013 at 5:12 am

      all module config are merged, and the view helper should only called if that called, there is no concept like you mentioned :p

  14. Sumit said, on May 28, 2013 at 8:00 pm

    Good work mate! your expertise and this blog has really been helpful. I just have suggestion if you can put a demo link of the sample code it would be great as people can see the actual working of the code bits. Cheers!

  15. teolateo said, on June 7, 2013 at 2:53 pm

    help me!

    Database
    CREATE TABLE IF NOT EXISTS `Menu` (
    `idmenu` int(2) NOT NULL AUTO_INCREMENT,
    `NameMenu` varchar(255) NOT NULL,
    PRIMARY KEY (`idmenu`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;

    NSERT INTO `Menu` (`idmenu`, `NameMenu`, ) VALUES
    (1, ‘Home’),
    (2, ‘Who we are’),
    (3, ‘Products’),
    (4, ‘Downloads’),
    (5, ‘Search’),
    (6, ‘Logon’),
    (7, ‘Contact us’);

    Module
    Ema
    –config
    –module.config.php
    –src
    –ema\view\helper\
    –MenuHelper.php
    –view
    –layout
    –layout.phtml
    –Module.php
    –autoload_classmap.php

    1.File module.config.php
    array(
    ‘invokables’=> array(
    ‘menus’ => ‘Ema\View\Helper\MenuHelper’,
    )
    ),
    );

    2.MenuHelper.php
    namespace Ema\View\Helper;
    use Zend\View\Helper\AbstractHelper;
    use Zend\Db\Adapter\Adapter;
    class MenuHelper extends AbstractHelper {
    Protected $adapter;
    public function __construct(Adapter $adapter) {
    $this->adapter = $adapter;
    }
    public function __invoke()
    { $result = $this->adapter->query(‘SELECT * FROM `Menu` ‘);
    return $result->toArray(); }
    }

    3.layout.phtml

    $menus as $menu){
    ?>

    error lauoyt.php foreach($this->$menus as $menu)

    • teolateo said, on June 7, 2013 at 2:57 pm

      Database
      CREATE TABLE IF NOT EXISTS `Menu` (
      `idmenu` int(2) NOT NULL AUTO_INCREMENT,
      `NameMenu` varchar(255) NOT NULL,
      PRIMARY KEY (`idmenu`)
      ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;

      NSERT INTO `Menu` (`idmenu`, `NameMenu`, ) VALUES
      (1, ‘Home’),
      (2, ‘Who we are’),
      (3, ‘Products’),
      (4, ‘Downloads’),
      (5, ‘Search’),
      (6, ‘Logon’),
      (7, ‘Contact us’);

      Module
      Ema
      –config
      –module.config.php
      –src
      –ema\view\helper\
      –MenuHelper.php
      –view
      –layout
      –layout.phtml
      –Module.php
      –autoload_classmap.php
      1.File module.config.php
      array(
      ‘invokables’=> array(
      ‘menus’ => ‘Ema\View\Helper\MenuHelper’,
      )
      ),
      );

      2.MenuHelper.php
      namespace Ema\View\Helper;
      use Zend\View\Helper\AbstractHelper;
      use Zend\Db\Adapter\Adapter;
      class MenuHelper extends AbstractHelper {
      Protected $adapter;
      public function __construct(Adapter $adapter)
      {
      $this->adapter = $adapter;
      }
      public function __invoke()
      {
      $result = $this->adapter->query(‘SELECT * FROM `Menu` ‘);
      return $result->toArray();
      }
      }
      3.layout.phtml

      $menus as $menu){
      ?>

  16. Beneetha TA said, on July 11, 2013 at 7:11 pm

    hi

    I am trying to do navigation with menu and sub menu but not getting……Could you please help me

  17. […] Weißt du denn, wie eigene View-Helper eingebunden werden? Ansonsten verweise ich einfach mal auf Zend Framework 2 : Create Your Custom View Helper | Welcome to Abdul Malik Ikhsan's Blog An die __invoke-Methode übergibst du dann die Formular-Elemente. In dieser baust du dann einfach […]

  18. Lom said, on October 6, 2013 at 10:32 pm

    Great tutorial! One question: How to get the translator working / conform inside a view helper? Possible?

    • samsonasik said, on October 6, 2013 at 10:34 pm

      you can call $this->view->viewhelpername() inside the view helper class.

  19. Lom said, on October 6, 2013 at 11:40 pm

    Thanks for your really quick reply :-). Sorry, maybe my question was not good.

    How can i use the translator->translate(); within a view helper to translate some needed strings? And does it has an impact on the performance if I se the translator inside a view helper.

    • samsonasik said, on October 6, 2013 at 11:47 pm

      call via :

      $this->view->translate("somestring");
      

      inside view helper.

  20. Lom said, on October 6, 2013 at 11:50 pm

    You’re the best! Thanks a lot! Now I’m even more think that the ZF2 is really awesome. Getting more and more comfortable with it. And still a lot to learn and discover :-).

  21. Arvind Kumar said, on October 8, 2013 at 2:08 pm

    Hello samsonasik,
    Thanks for sharing this grate tutorial. Can I make multiple function in Testhelper.php file like sortString,uppercase,lowercase etc. If It is possible then how will I use.
    Thanks in advenced.

    • samsonasik said, on October 8, 2013 at 3:11 pm

      ofcourse, as far as the access modifier of that function is public. you can do

      $this->yourhelper()->somefunction();
      
  22. Arvind Kumar said, on October 8, 2013 at 7:19 pm

    How to define and access multiple function from one helper class

    test_helper->calculatetotal(20);
    $this->test_helper->calculatearea(30);

    Thanks in advance for reply :)

    • Arvind Kumar said, on October 8, 2013 at 7:21 pm

      class Testhelper extends AbstractHelper
      {
      public $sum;
      public function __invoke()
      {
      return $this;
      }

      public function calculatetotal($sum)
      {
      return $sum+$sum;
      }
      public function calculatearea($sum)
      {
      return $sum*$sum;
      }

      }

    • samsonasik said, on October 8, 2013 at 8:53 pm

      $this->test_helper()->calculatearea(30);

      you missed () to get the __invoke()/__construct() function first.

      • Arvind Kumar said, on October 8, 2013 at 9:20 pm

        Thanks got it :)

        $this->test_helper()->setUserName(‘test’)

  23. hungbuit said, on October 26, 2013 at 3:11 pm

    thank so much!

  24. Juan D said, on November 28, 2013 at 5:39 am

    I’m having problems trying to create my own FormRow based on Zend2 with just few changes on how render create the layout and where errors are placed. I’ve created my own FormRow class, adding this class to invokables

    public function getViewHelperConfig()
    {
    return array(
    ‘invokables’ => array(‘formelementerrors’ => ‘Events\Form\View\Helper\FormElementErrors’,
    ‘formrow’ => ‘Events\Form\View\Helper\FormRow’),
    );

    But getting this error and I’m a little bit lost. Can you give me a little bit of your zend2 wisdom to guide me?

    Argument 1 passed toXXXXX\\FormRow::render() must be an instance of Events\\Form\\View\\Helper\\ElementInterface, instance of Zend\\Form\\Element\\Select given, called in XXXX/vendor/zendframework/zendframework/library/Zend/Form/View/Helper/FormRow.php on line 107

    Thanks

  25. […] post about creating Controller pLugin in ZF2. For what have to do to create a View Helper , see : my post about creating view helper or EvanDotPro’s […]

  26. Mohammad Nomaan Patel said, on January 23, 2014 at 8:40 pm

    Hi,
    I would like to create view helper for setting attributes for select options
    For example

    128 x 128

    64 x 64


    This width & height attribute would be set on runtime.
    Plz Help

  27. Mohammad Nomaan Patel said, on January 23, 2014 at 8:50 pm
    <select>
    	<option value="1" width="128" height="128">
    		128 x 128
    	</option>
    	<option value="2" width="64" height="64">
    		64 x 64
    	</option>
    </select>
    

    Sorry for posting this replies multiple times…….

  28. Flavio Portela said, on March 8, 2014 at 4:34 am

    Reblogged this on Flavio's Blog and commented:
    Ejemplo para crear Views Helpers en ZF2

  29. Iwan said, on May 6, 2014 at 11:27 am

    Om, mau tanya.. kalau mau buat fungsi tanggal, hari ,bulan versi Indonesia, harus pake view helper kah om??
    boleh kasih sedikit tips ga sama ane.. masih baru belajar om… :)

    Makasih banyak om…

  30. Amit said, on July 22, 2014 at 4:05 pm

    Hello Samsonasik,
    I need your help .
    I want to show some data from model to footer.phtml/layout.phtml .
    I am trying it with custom view helper but there is problem of database connectivity .
    is there another way to do this .

    If i seprate header.phtml ,footer.phtml and menu.phtml and want to some data module wise then how shoild i approach please help.

  31. දිනුක තිලංග said, on October 22, 2014 at 8:53 pm

    Thanks. It is works for me.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 261 other followers

%d bloggers like this: