How to Enable Form View Helpers in Zend Expressive

Zend Expressive is a great foundation on which to build an application, especially if you want to keep it small and lean. But out of the box, form view helpers aren’t available. Here’s how to make them available.


Zend Expressive is a great foundation on which to build an application, especially if you want to keep it small and lean. But out of the box, form view helpers aren’t available. Here’s how to make them available.


Recently, as I’ve been continuing my journey learning all about Zend Expressive, primarily by building a client application with it, I’ve consistently learned just how much of an improvement it is over the previous approach of the Zend Skeleton project.

For what it’s worth, I’m not wanting to detract from the Zend Skeleton project. It’s an excellent one, one well worth using as a foundation for a wide variety of projects.

However Zend Expressive, at least to me, is the next step in the continuing evolution of Zend Framework. It’s a lot lighter, a lot less involved, and all round, a lot simpler to work with.

But, given that it’s a microframework approach, there’s a lot of features which it doesn’t implement out of the box; features which you might expect to be automatically available, depending on your previous development experience.

So it was with me, when it came time to build and render the login form for the application. I assumed that I’d be able to use the Zend\View form helpers which I’d come to rely on for so long, in my templates.

Well, no I couldn’t.

I was a bit lost at first as to why they’d not be available. But I reminded myself that I was now working with a microframework, not a full-stack framework. And when that’s your starting point, why would you have form view helpers available by default?

They’re not essential to building an application. They’re an optional, nice-to-have, feature, one which you’d bring in later. They’re one which, whilst they make life easier when they’re present, aren’t strictly necessary.

For me however, they really make building the kinds of applications I develop easier. So I wanted to make the available. The question was, how?

What To Do?

As always, I asked both on the Zend Framework 2 Facebook group, and in #zftalk on IRC. Abdul Malik Ikhsan was kind enough to answer my enquiry by saying:

If you need another view helpers except url and serverurl, may need to create custom ZendViewRendererFactory and point expressive renderer to your own factory

What is ZendViewRendererFactory?

So I started exploring the class and found that that was the right class to start with. It sets up the Zend\View service, when Zend\View is used as the view layer with Zend Expressive.

It has a private method, injectHelpers, which injects two helpers, url and serverurl into the list of available helpers. However, given that the method has private visibility, I couldn’t override the method in a sub-class.

Doing so would always result in the parent method being called. So I created a new class called App\ServiceManager\Factories\ViewRendererFactory.php. If you’re wondering why that namespace, it’s a clear, logical, and consistent naming convention.

Injecting the Form ViewHelpers

Now that I had my class which would handle injecting the form view helpers, in addition to the existing two, the question was, how would I actually inject them? If you have a look in ZendViewRendererFactory, in the injectHelpers method, you’ll see the following line:

$helpers->setInvokableClass('serverurl', ServerUrlHelper::class);

What it does is to add a view helper to the helpers list, specifying the name it will be referred to by the first parameter, and the invokable class which provides the functionality as the second.

Ok, not so hard. I just have to now do that for all the form view helpers. To do that though, we first have to make them available. Gladly, they’re nicely packaged up in the zend-form package.

If you don’t have them available in your package, use Composer to add them by calling composer require zendframework/zend-form from the project root. Then, under vendor/zendframework/zend-form/src/View/Helper you’ll see that there’s thirty nine of them.

You might be thinking, at this point, that we’re going to have to add thirty nine calls to setInvokableClass to add them all. What a lot of work that’d be?

A Simple Way to Inject the ViewHelpers

Well no, we don’t have to. Why? Because under vendor/zendframework/zend-form/src/View/ is a file called HelperConfig.php. Originally designed to be used with the ZF2 ServiceManager, it has a protected associative array, called $invokables, which contains the name and class information which we need.

However we can’t use it directly, as there’s no method available to retrieve $invokables. But not to worry, to retrieve the array, we next create a new class, called App\Form\View\HelperConfig.php which extends HelperConfig.php, as below.

<?php

namespace App\Form\View;

use Zend\Form\View\HelperConfig as BaseHelperConfig;

class HelperConfig extends BaseHelperConfig
{
    public function retrieveInvokables()
    {
        return $this->invokables;
    }
}

In the class, you can see that I’ve added a new, public, method, which returns $invokables. Using that, we can now retrieve our list of invokables, and inject them in to the available list of helpers.

To do that, though it feels like a clear case of code duplication, I first copied the __invoke and injectHelpers methods to my new ViewRendererFactory class. Then, after the previous call to setInvokableClass, I added the following code.

$helperConfig = \App\Form\View\HelperConfig();

foreach ($helperConfig->retrieveInvokables() as $key => $value)
{
    $helpers->setInvokableClass($key, $value);
}

This will retrieve and iterate over the list of invokables adding them to the available list. With that done, I’ve added all the form view helpers to the list of available helpers; a list which can be changed later, if needed.

Updating the ServiceLocator Configuration

Now, there’s only one more thing to do; we need to update the service locator dependency configuration to use the new renderer factory, instead of the default. To do that, in config/autoload/templates.global.php, update it so that it looks as follows.

'dependencies' => [
    'factories' => [
        'Zend\Expressive\FinalHandler' =>
            Zend\Expressive\Container\TemplatedErrorHandlerFactory::class,
        Zend\Expressive\Template\TemplateRendererInterface::class =>
            App\ServiceManager\Factories\TelcoSwitchViewRendererFactory::class,
    ],
],

What this will do is tell it to use our new class for instantiating the view renderer, instead of the default.

Don’t Forget Composer

One last thing, if you’re following along, make sure that you run composer dumpautoload --optimize so that your new classes are made available via Composer’s autoloader. Otherwise you’ll encounter an exception when you run the code.

With all these changes made, we can now use Form ViewHelpers in our .phtml templates as we could with Zend Framework 2, using the ZF2 Skeleton App project.

## Over to You

Are you rendering forms in your Zend Expressive applications? How have you implemented them? What’s your experience with it? Share your thoughts in the comments and let’s have a hearty conversation about it.


You might also be interested in these tutorials too...

Mon, Nov 9, 2015

Introduction to Zend Expressive (Part 2)

Over the last number of months the Zend Framework team’s been hard at work on Zend Framework 3. And there are major changes afoot. In this 2-part series, we look at one of the core components - Zend Expressive.

Mon, Nov 2, 2015

Introduction to Zend Expressive

Over the last number of months the Zend Framework team’s been hard at work on Zend Framework 3. And there are major changes afoot. In this 2-part series, we look at one of the core components - Zend Expressive.

Why Is My Website So Slow?!
Fri, Sep 27, 2019

Why Is My Website So Slow?!

Is your website (or web-based application) not performing like you expect it should? Not sure why or what to do about it? Then come learn about some key things you can do to have your website perform properly.

Tue, Jun 26, 2018

What Are Delegator Factories and Why You Should Use Them

Ever wanted to dynamically expand the functionality of an object which you retrieve from your dependency injection container, based on different needs, yet without creating messy, hard to maintain configurations? Then you’re going to want to know about a powerful new technique - called Delegator Factories.


Want more tutorials like this?

If so, enter your email address in the field below and click subscribe.

You can unsubscribe at any time by clicking the link in the footer of the emails you'll receive. Here's my privacy policy, if you'd like to know more. I use Mailchimp to send emails. You can learn more about their privacy practices here.

Join the discussion

comments powered by Disqus