Zend-Expressive and Plates



In the zend-expressive-skeleton, the template engine plates is the default.
Unfortunately no tutorials or how-tos exist in the wild.
How is it possible to enable plates extensions in zend-expressive, such as the uri-extension?
Well, I can add to configuration, e.g. templates.global.php:

     'plates' => [
         'extensions' => [

But how to pass the required extra parameter?

Thanks in advance,


Set PlatesEngine::class to container.

Create a middleware and pass PlatesEngine::class and needed values ( extensions etc ? ) to the constructor and that can register the extension.


First, the Plates integration for Expressive ships with its own extensions for handling URIs (view source — it registers both a url() and a serverurl() function) which is engineered to work with whatever zend-expressive-router implementation you are using; you should definitely use this in most cases.

Second, as @harikt notes, you could manipulate the PlatesEngine within middleware.

Third, as you noted, you can provide configuration via the plates.extensions key. These can be any of:

  • instances
  • directly instantiable class names
  • service names

If the extension needs arguments in order to work, create a factory for the extension, register that factory for the extension name, and then use the service name of the extension in your configuration.

The last solution is the best one if your extension needs arguments, as it ensures that the factory is not called unless the middleware being dispatched in the current request needs a renderer.

However, if the extension relies on information that is based on the request, the middleware path is likely the best solution. If you absolutely require that you use the uri() extension, for instance, I’d write middleware like the following:

function (ServerRequestInterface $request, DelegateInterface $delegate) use (PlatesEngine $engine) {
    $extension = new URI($request->getUri()->getPath());
    return $delegate->process($request);

Note that I’m pulling the path information from the request, and not a superglobal; this is more testable, and ensures that the path provided is the same that the request is using, regardless of the web server being used.


Thanks a lot for the quick reply!
This is a very valuable platform for me!