Pragmatism in the real world

Configuring a ZF2 view helper before rendering

The currencyFormat view helper is very easy to use:

echo $this->currencyFormat($value, 'GBP', 'en_GB');

When I was reading the documentation for the currencyFormat view helper, I discovered that you could configure the currency code and locale once rather than in every call:

// Within your view script
$this->plugin("currencyformat")->setCurrencyCode("GBP")->setLocale("en_GB");

This is obviously useful, but even more useful would be if we could set it once by default and then override if we need to in a specific call.

The easiest way to do this is to use an event listener on the renderer.post View event within a modules’s onBootstrap method, like this:

namespace Application;

use Zend\View\ViewEvent;
use Zend\View\Renderer\PhpRenderer;
class Module
{
    public function onBootstrap($e)
    {
        $events = $e->getApplication()->getEventManager();
        $sharedEvents = $events->getSharedManager();
        $sharedEvents->attach('Zend\View\View', ViewEvent::EVENT_RENDERER_POST, function($event) {
            $renderer = $event->getRenderer();
            if ($renderer instanceof PhpRenderer) {
                $renderer->plugin("currencyformat")->setCurrencyCode("GBP")->setLocale('en_GB');
            }
        });
    }
    // ...
}

Now we can simply do call currencyFormat() with the value in our view script:

echo $this->currencyFormat($value);

9 thoughts on “Configuring a ZF2 view helper before rendering

  1. Nice one Rob. We've also got a method in our own AbstractActionController called `getViewHelper($helperName)` which basically just does this:

    return $this->getServiceLocator()->get('viewhelpermanager')->get($helperName);

    I think it is useful if you need to "configure" a view helper on a per-action basis (rather than on a global basis like your example).

  2. This may be a rookie question, but where does $sm from 'use($sm)' get defined in your onBootstrap method above?

  3. Mike, It's an error based on where I copied the code from and isn't needed for this specific sample.

    Fixed now. Thanks!

  4. I think that better approach is to add initializer to the ViewHelperManager. So if you already have getViewHelperConfig() method in your Module.php, add "initializers" section to its return value:

    public function getViewHelperConfig()
    {
        return array(
            'initializers' => array(
                function($helper, ServiceLocatorInterface $serviceLocator) {
                    if ($helper instanceof Currencyformat) {
                        $helper->setCurrencyCode("GBP")->setLocale('en_GB');
                    }
                }
            ),
        );
    }
    
  5. I use this Method to add the Dojotoolkit to the HeadScript but as test, i noticed that the 'ZendViewView' triggers twice is there any hook that calls only once during the Render event. thanks :)

  6. Nice post. But i like the solution to set up my view helpers in module.config.php, like this:

    return array(
    //...
    'view_helpers' => array(
    		'factories' => array(
    			'formElementErrors' => function($sm) {
    				$helper = new FormElementErrors();
    				$helper->setAttributes(array('class' => 'ul-error'));
    				return $helper;
    			},
    			'currencyFormat' => function($sm) {
    				$helper = new CurrencyFormat();
    				$helper->setCurrencyCode("CHF");
    				$helper->setLocale('de_CH');
    				return $helper;
    			},
    			'dateFormat' => function($sm) {
    				$helper = new DateFormat();
    				$helper->setLocale('de_CH');
    				return $helper;
    			}
    		),
    )
    );
    
    
    				
  7. Matt,

    Be aware that if you do it that way, then the ModuleManager can no longer cache the merged config.

    Regards,

    Rob…

Comments are closed.